DDC Tool
Loading...
Searching...
No Matches
json.hpp
Go to the documentation of this file.
1/*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4| | |__ | | | | | | version 3.10.4
5|_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8SPDX-License-Identifier: MIT
9Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10
11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal
13in the Software without restriction, including without limitation the rights
14to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15copies of the Software, and to permit persons to whom the Software is
16furnished to do so, subject to the following conditions:
17
18The above copyright notice and this permission notice shall be included in all
19copies or substantial portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27SOFTWARE.
28*/
29
30#ifndef INCLUDE_NLOHMANN_JSON_HPP_
31#define INCLUDE_NLOHMANN_JSON_HPP_
32
33#define NLOHMANN_JSON_VERSION_MAJOR 3
34#define NLOHMANN_JSON_VERSION_MINOR 10
35#define NLOHMANN_JSON_VERSION_PATCH 4
36
37#include <algorithm> // all_of, find, for_each
38#include <cstddef> // nullptr_t, ptrdiff_t, size_t
39#include <functional> // hash, less
40#include <initializer_list> // initializer_list
41#ifndef JSON_NO_IO
42 #include <iosfwd> // istream, ostream
43#endif // JSON_NO_IO
44#include <iterator> // random_access_iterator_tag
45#include <memory> // unique_ptr
46#include <numeric> // accumulate
47#include <string> // string, stoi, to_string
48#include <utility> // declval, forward, move, pair, swap
49#include <vector> // vector
50
51// #include <nlohmann/adl_serializer.hpp>
52
53
54#include <type_traits>
55#include <utility>
56
57// #include <nlohmann/detail/conversions/from_json.hpp>
58
59
60#include <algorithm> // transform
61#include <array> // array
62#include <forward_list> // forward_list
63#include <iterator> // inserter, front_inserter, end
64#include <map> // map
65#include <string> // string
66#include <tuple> // tuple, make_tuple
67#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
68#include <unordered_map> // unordered_map
69#include <utility> // pair, declval
70#include <valarray> // valarray
71
72// #include <nlohmann/detail/exceptions.hpp>
73
74
75#include <exception> // exception
76#include <stdexcept> // runtime_error
77#include <string> // to_string
78#include <vector> // vector
79
80// #include <nlohmann/detail/value_t.hpp>
81
82
83#include <array> // array
84#include <cstddef> // size_t
85#include <cstdint> // uint8_t
86#include <string> // string
87
88namespace nlohmann
89{
90namespace detail
91{
93// JSON type enumeration //
95
120enum class value_t : std::uint8_t
121{
122 null,
123 object,
124 array,
125 string,
126 boolean,
130 binary,
131 discarded
132};
133
147inline bool operator<(const value_t lhs, const value_t rhs) noexcept
148{
149 static constexpr std::array<std::uint8_t, 9> order = {{
150 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
151 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
152 6 /* binary */
153 }
154 };
155
156 const auto l_index = static_cast<std::size_t>(lhs);
157 const auto r_index = static_cast<std::size_t>(rhs);
158 return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
159}
160} // namespace detail
161} // namespace nlohmann
162
163// #include <nlohmann/detail/string_escape.hpp>
164
165
166#include <string>
167// #include <nlohmann/detail/macro_scope.hpp>
168
169
170#include <utility> // declval, pair
171// #include <nlohmann/thirdparty/hedley/hedley.hpp>
172
173
174/* Hedley - https://nemequ.github.io/hedley
175 * Created by Evan Nemerson <evan@nemerson.com>
176 *
177 * To the extent possible under law, the author(s) have dedicated all
178 * copyright and related and neighboring rights to this software to
179 * the public domain worldwide. This software is distributed without
180 * any warranty.
181 *
182 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
183 * SPDX-License-Identifier: CC0-1.0
184 */
185
186#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
187#if defined(JSON_HEDLEY_VERSION)
188 #undef JSON_HEDLEY_VERSION
189#endif
190#define JSON_HEDLEY_VERSION 15
191
192#if defined(JSON_HEDLEY_STRINGIFY_EX)
193 #undef JSON_HEDLEY_STRINGIFY_EX
194#endif
195#define JSON_HEDLEY_STRINGIFY_EX(x) #x
196
197#if defined(JSON_HEDLEY_STRINGIFY)
198 #undef JSON_HEDLEY_STRINGIFY
199#endif
200#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
201
202#if defined(JSON_HEDLEY_CONCAT_EX)
203 #undef JSON_HEDLEY_CONCAT_EX
204#endif
205#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
206
207#if defined(JSON_HEDLEY_CONCAT)
208 #undef JSON_HEDLEY_CONCAT
209#endif
210#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
211
212#if defined(JSON_HEDLEY_CONCAT3_EX)
213 #undef JSON_HEDLEY_CONCAT3_EX
214#endif
215#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
216
217#if defined(JSON_HEDLEY_CONCAT3)
218 #undef JSON_HEDLEY_CONCAT3
219#endif
220#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
221
222#if defined(JSON_HEDLEY_VERSION_ENCODE)
223 #undef JSON_HEDLEY_VERSION_ENCODE
224#endif
225#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
226
227#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
228 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
229#endif
230#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
231
232#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
233 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
234#endif
235#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
236
237#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
238 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
239#endif
240#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
241
242#if defined(JSON_HEDLEY_GNUC_VERSION)
243 #undef JSON_HEDLEY_GNUC_VERSION
244#endif
245#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
246 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
247#elif defined(__GNUC__)
248 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
249#endif
250
251#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
252 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
253#endif
254#if defined(JSON_HEDLEY_GNUC_VERSION)
255 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
256#else
257 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
258#endif
259
260#if defined(JSON_HEDLEY_MSVC_VERSION)
261 #undef JSON_HEDLEY_MSVC_VERSION
262#endif
263#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
264 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
265#elif defined(_MSC_FULL_VER) && !defined(__ICL)
266 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
267#elif defined(_MSC_VER) && !defined(__ICL)
268 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
269#endif
270
271#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
272 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
273#endif
274#if !defined(JSON_HEDLEY_MSVC_VERSION)
275 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
276#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
277 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
278#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
279 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
280#else
281 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
282#endif
283
284#if defined(JSON_HEDLEY_INTEL_VERSION)
285 #undef JSON_HEDLEY_INTEL_VERSION
286#endif
287#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
288 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
289#elif defined(__INTEL_COMPILER) && !defined(__ICL)
290 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
291#endif
292
293#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
294 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
295#endif
296#if defined(JSON_HEDLEY_INTEL_VERSION)
297 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
298#else
299 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
300#endif
301
302#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
303 #undef JSON_HEDLEY_INTEL_CL_VERSION
304#endif
305#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
306 #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
307#endif
308
309#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
310 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
311#endif
312#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
313 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
314#else
315 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
316#endif
317
318#if defined(JSON_HEDLEY_PGI_VERSION)
319 #undef JSON_HEDLEY_PGI_VERSION
320#endif
321#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
322 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
323#endif
324
325#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
326 #undef JSON_HEDLEY_PGI_VERSION_CHECK
327#endif
328#if defined(JSON_HEDLEY_PGI_VERSION)
329 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
330#else
331 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
332#endif
333
334#if defined(JSON_HEDLEY_SUNPRO_VERSION)
335 #undef JSON_HEDLEY_SUNPRO_VERSION
336#endif
337#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
338 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
339#elif defined(__SUNPRO_C)
340 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
341#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
342 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
343#elif defined(__SUNPRO_CC)
344 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
345#endif
346
347#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
348 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
349#endif
350#if defined(JSON_HEDLEY_SUNPRO_VERSION)
351 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
352#else
353 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
354#endif
355
356#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
357 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
358#endif
359#if defined(__EMSCRIPTEN__)
360 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
361#endif
362
363#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
364 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
365#endif
366#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
367 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
368#else
369 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
370#endif
371
372#if defined(JSON_HEDLEY_ARM_VERSION)
373 #undef JSON_HEDLEY_ARM_VERSION
374#endif
375#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
376 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
377#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
378 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
379#endif
380
381#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
382 #undef JSON_HEDLEY_ARM_VERSION_CHECK
383#endif
384#if defined(JSON_HEDLEY_ARM_VERSION)
385 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
386#else
387 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
388#endif
389
390#if defined(JSON_HEDLEY_IBM_VERSION)
391 #undef JSON_HEDLEY_IBM_VERSION
392#endif
393#if defined(__ibmxl__)
394 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
395#elif defined(__xlC__) && defined(__xlC_ver__)
396 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
397#elif defined(__xlC__)
398 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
399#endif
400
401#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
402 #undef JSON_HEDLEY_IBM_VERSION_CHECK
403#endif
404#if defined(JSON_HEDLEY_IBM_VERSION)
405 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
406#else
407 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
408#endif
409
410#if defined(JSON_HEDLEY_TI_VERSION)
411 #undef JSON_HEDLEY_TI_VERSION
412#endif
413#if \
414 defined(__TI_COMPILER_VERSION__) && \
415 ( \
416 defined(__TMS470__) || defined(__TI_ARM__) || \
417 defined(__MSP430__) || \
418 defined(__TMS320C2000__) \
419 )
420#if (__TI_COMPILER_VERSION__ >= 16000000)
421 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
422#endif
423#endif
424
425#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
426 #undef JSON_HEDLEY_TI_VERSION_CHECK
427#endif
428#if defined(JSON_HEDLEY_TI_VERSION)
429 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
430#else
431 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
432#endif
433
434#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
435 #undef JSON_HEDLEY_TI_CL2000_VERSION
436#endif
437#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
438 #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
439#endif
440
441#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
442 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
443#endif
444#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
445 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
446#else
447 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
448#endif
449
450#if defined(JSON_HEDLEY_TI_CL430_VERSION)
451 #undef JSON_HEDLEY_TI_CL430_VERSION
452#endif
453#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
454 #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
455#endif
456
457#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
458 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
459#endif
460#if defined(JSON_HEDLEY_TI_CL430_VERSION)
461 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
462#else
463 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
464#endif
465
466#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
467 #undef JSON_HEDLEY_TI_ARMCL_VERSION
468#endif
469#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
470 #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
471#endif
472
473#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
474 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
475#endif
476#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
477 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
478#else
479 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
480#endif
481
482#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
483 #undef JSON_HEDLEY_TI_CL6X_VERSION
484#endif
485#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
486 #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
487#endif
488
489#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
490 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
491#endif
492#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
493 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
494#else
495 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
496#endif
497
498#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
499 #undef JSON_HEDLEY_TI_CL7X_VERSION
500#endif
501#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
502 #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
503#endif
504
505#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
506 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
507#endif
508#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
509 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
510#else
511 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
512#endif
513
514#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
515 #undef JSON_HEDLEY_TI_CLPRU_VERSION
516#endif
517#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
518 #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
519#endif
520
521#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
522 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
523#endif
524#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
525 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
526#else
527 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
528#endif
529
530#if defined(JSON_HEDLEY_CRAY_VERSION)
531 #undef JSON_HEDLEY_CRAY_VERSION
532#endif
533#if defined(_CRAYC)
534 #if defined(_RELEASE_PATCHLEVEL)
535 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
536 #else
537 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
538 #endif
539#endif
540
541#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
542 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
543#endif
544#if defined(JSON_HEDLEY_CRAY_VERSION)
545 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
546#else
547 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
548#endif
549
550#if defined(JSON_HEDLEY_IAR_VERSION)
551 #undef JSON_HEDLEY_IAR_VERSION
552#endif
553#if defined(__IAR_SYSTEMS_ICC__)
554 #if __VER__ > 1000
555 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
556 #else
557 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
558 #endif
559#endif
560
561#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
562 #undef JSON_HEDLEY_IAR_VERSION_CHECK
563#endif
564#if defined(JSON_HEDLEY_IAR_VERSION)
565 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
566#else
567 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
568#endif
569
570#if defined(JSON_HEDLEY_TINYC_VERSION)
571 #undef JSON_HEDLEY_TINYC_VERSION
572#endif
573#if defined(__TINYC__)
574 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
575#endif
576
577#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
578 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
579#endif
580#if defined(JSON_HEDLEY_TINYC_VERSION)
581 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
582#else
583 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
584#endif
585
586#if defined(JSON_HEDLEY_DMC_VERSION)
587 #undef JSON_HEDLEY_DMC_VERSION
588#endif
589#if defined(__DMC__)
590 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
591#endif
592
593#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
594 #undef JSON_HEDLEY_DMC_VERSION_CHECK
595#endif
596#if defined(JSON_HEDLEY_DMC_VERSION)
597 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
598#else
599 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
600#endif
601
602#if defined(JSON_HEDLEY_COMPCERT_VERSION)
603 #undef JSON_HEDLEY_COMPCERT_VERSION
604#endif
605#if defined(__COMPCERT_VERSION__)
606 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
607#endif
608
609#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
610 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
611#endif
612#if defined(JSON_HEDLEY_COMPCERT_VERSION)
613 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
614#else
615 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
616#endif
617
618#if defined(JSON_HEDLEY_PELLES_VERSION)
619 #undef JSON_HEDLEY_PELLES_VERSION
620#endif
621#if defined(__POCC__)
622 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
623#endif
624
625#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
626 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
627#endif
628#if defined(JSON_HEDLEY_PELLES_VERSION)
629 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
630#else
631 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
632#endif
633
634#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
635 #undef JSON_HEDLEY_MCST_LCC_VERSION
636#endif
637#if defined(__LCC__) && defined(__LCC_MINOR__)
638 #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
639#endif
640
641#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
642 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
643#endif
644#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
645 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
646#else
647 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
648#endif
649
650#if defined(JSON_HEDLEY_GCC_VERSION)
651 #undef JSON_HEDLEY_GCC_VERSION
652#endif
653#if \
654 defined(JSON_HEDLEY_GNUC_VERSION) && \
655 !defined(__clang__) && \
656 !defined(JSON_HEDLEY_INTEL_VERSION) && \
657 !defined(JSON_HEDLEY_PGI_VERSION) && \
658 !defined(JSON_HEDLEY_ARM_VERSION) && \
659 !defined(JSON_HEDLEY_CRAY_VERSION) && \
660 !defined(JSON_HEDLEY_TI_VERSION) && \
661 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
662 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
663 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
664 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
665 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
666 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
667 !defined(__COMPCERT__) && \
668 !defined(JSON_HEDLEY_MCST_LCC_VERSION)
669 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
670#endif
671
672#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
673 #undef JSON_HEDLEY_GCC_VERSION_CHECK
674#endif
675#if defined(JSON_HEDLEY_GCC_VERSION)
676 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
677#else
678 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
679#endif
680
681#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
682 #undef JSON_HEDLEY_HAS_ATTRIBUTE
683#endif
684#if \
685 defined(__has_attribute) && \
686 ( \
687 (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
688 )
689# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
690#else
691# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
692#endif
693
694#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
695 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
696#endif
697#if defined(__has_attribute)
698 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
699#else
700 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
701#endif
702
703#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
704 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
705#endif
706#if defined(__has_attribute)
707 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
708#else
709 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
710#endif
711
712#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
713 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
714#endif
715#if \
716 defined(__has_cpp_attribute) && \
717 defined(__cplusplus) && \
718 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
719 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
720#else
721 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
722#endif
723
724#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
725 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
726#endif
727#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
728 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
729#elif \
730 !defined(JSON_HEDLEY_PGI_VERSION) && \
731 !defined(JSON_HEDLEY_IAR_VERSION) && \
732 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
733 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
734 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
735#else
736 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
737#endif
738
739#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
740 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
741#endif
742#if defined(__has_cpp_attribute) && defined(__cplusplus)
743 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
744#else
745 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
746#endif
747
748#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
749 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
750#endif
751#if defined(__has_cpp_attribute) && defined(__cplusplus)
752 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
753#else
754 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
755#endif
756
757#if defined(JSON_HEDLEY_HAS_BUILTIN)
758 #undef JSON_HEDLEY_HAS_BUILTIN
759#endif
760#if defined(__has_builtin)
761 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
762#else
763 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
764#endif
765
766#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
767 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
768#endif
769#if defined(__has_builtin)
770 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
771#else
772 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
773#endif
774
775#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
776 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
777#endif
778#if defined(__has_builtin)
779 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
780#else
781 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
782#endif
783
784#if defined(JSON_HEDLEY_HAS_FEATURE)
785 #undef JSON_HEDLEY_HAS_FEATURE
786#endif
787#if defined(__has_feature)
788 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
789#else
790 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
791#endif
792
793#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
794 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
795#endif
796#if defined(__has_feature)
797 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
798#else
799 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
800#endif
801
802#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
803 #undef JSON_HEDLEY_GCC_HAS_FEATURE
804#endif
805#if defined(__has_feature)
806 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
807#else
808 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
809#endif
810
811#if defined(JSON_HEDLEY_HAS_EXTENSION)
812 #undef JSON_HEDLEY_HAS_EXTENSION
813#endif
814#if defined(__has_extension)
815 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
816#else
817 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
818#endif
819
820#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
821 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
822#endif
823#if defined(__has_extension)
824 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
825#else
826 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
827#endif
828
829#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
830 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
831#endif
832#if defined(__has_extension)
833 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
834#else
835 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
836#endif
837
838#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
839 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
840#endif
841#if defined(__has_declspec_attribute)
842 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
843#else
844 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
845#endif
846
847#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
848 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
849#endif
850#if defined(__has_declspec_attribute)
851 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
852#else
853 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
854#endif
855
856#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
857 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
858#endif
859#if defined(__has_declspec_attribute)
860 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
861#else
862 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
863#endif
864
865#if defined(JSON_HEDLEY_HAS_WARNING)
866 #undef JSON_HEDLEY_HAS_WARNING
867#endif
868#if defined(__has_warning)
869 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
870#else
871 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
872#endif
873
874#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
875 #undef JSON_HEDLEY_GNUC_HAS_WARNING
876#endif
877#if defined(__has_warning)
878 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
879#else
880 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
881#endif
882
883#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
884 #undef JSON_HEDLEY_GCC_HAS_WARNING
885#endif
886#if defined(__has_warning)
887 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
888#else
889 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
890#endif
891
892#if \
893 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
894 defined(__clang__) || \
895 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
896 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
897 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
898 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
899 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
900 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
901 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
902 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
903 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
904 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
905 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
906 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
907 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
908 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
909 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
910 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
911 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
912#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
913 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
914#else
915 #define JSON_HEDLEY_PRAGMA(value)
916#endif
917
918#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
919 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
920#endif
921#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
922 #undef JSON_HEDLEY_DIAGNOSTIC_POP
923#endif
924#if defined(__clang__)
925 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
926 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
927#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
928 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
929 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
930#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
931 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
932 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
933#elif \
934 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
935 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
936 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
937 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
938#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
939 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
940 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
941#elif \
942 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
943 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
944 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
945 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
946 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
947 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
948 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
949 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
950#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
951 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
952 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
953#else
954 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
955 #define JSON_HEDLEY_DIAGNOSTIC_POP
956#endif
957
958/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
959 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
960#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
961 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
962#endif
963#if defined(__cplusplus)
964# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
965# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
966# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
967# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
968 JSON_HEDLEY_DIAGNOSTIC_PUSH \
969 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
970 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
971 _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
972 xpr \
973 JSON_HEDLEY_DIAGNOSTIC_POP
974# else
975# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
976 JSON_HEDLEY_DIAGNOSTIC_PUSH \
977 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
978 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
979 xpr \
980 JSON_HEDLEY_DIAGNOSTIC_POP
981# endif
982# else
983# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
984 JSON_HEDLEY_DIAGNOSTIC_PUSH \
985 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
986 xpr \
987 JSON_HEDLEY_DIAGNOSTIC_POP
988# endif
989# endif
990#endif
991#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
992 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
993#endif
994
995#if defined(JSON_HEDLEY_CONST_CAST)
996 #undef JSON_HEDLEY_CONST_CAST
997#endif
998#if defined(__cplusplus)
999# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1000#elif \
1001 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1002 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1003 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1004# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1005 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1006 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1007 ((T) (expr)); \
1008 JSON_HEDLEY_DIAGNOSTIC_POP \
1009 }))
1010#else
1011# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1012#endif
1013
1014#if defined(JSON_HEDLEY_REINTERPRET_CAST)
1015 #undef JSON_HEDLEY_REINTERPRET_CAST
1016#endif
1017#if defined(__cplusplus)
1018 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1019#else
1020 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1021#endif
1022
1023#if defined(JSON_HEDLEY_STATIC_CAST)
1024 #undef JSON_HEDLEY_STATIC_CAST
1025#endif
1026#if defined(__cplusplus)
1027 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1028#else
1029 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1030#endif
1031
1032#if defined(JSON_HEDLEY_CPP_CAST)
1033 #undef JSON_HEDLEY_CPP_CAST
1034#endif
1035#if defined(__cplusplus)
1036# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1037# define JSON_HEDLEY_CPP_CAST(T, expr) \
1038 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1039 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1040 ((T) (expr)) \
1041 JSON_HEDLEY_DIAGNOSTIC_POP
1042# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1043# define JSON_HEDLEY_CPP_CAST(T, expr) \
1044 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1045 _Pragma("diag_suppress=Pe137") \
1046 JSON_HEDLEY_DIAGNOSTIC_POP
1047# else
1048# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1049# endif
1050#else
1051# define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1052#endif
1053
1054#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1055 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1056#endif
1057#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1058 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1059#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1060 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1061#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1062 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1063#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1064 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1065#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1066 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1067#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1068 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1069#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1070 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1071#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1072 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1073#elif \
1074 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1075 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1076 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1077 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1078 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1079 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1080 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1081 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1082 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1083 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1084 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1085 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1086#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1087 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1088#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1089 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1090#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1091 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1092#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1093 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1094#else
1095 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1096#endif
1097
1098#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1099 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1100#endif
1101#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1102 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1103#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1104 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1105#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1106 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1107#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1108 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1109#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1110 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1111#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1112 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1113#elif \
1114 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1115 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1116 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1117 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1118 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1119#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1120 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1121#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1122 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1123#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1124 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1125#else
1126 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1127#endif
1128
1129#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1130 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1131#endif
1132#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1133 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1134#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1135 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1136#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1137 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1138#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1139 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1140#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1141 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1142#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1143 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1144#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1145 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1146#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1147 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1148#elif \
1149 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1150 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1151 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1152 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1153#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1154 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1155#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1156 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1157#else
1158 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1159#endif
1160
1161#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1162 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1163#endif
1164#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1165 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1166#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1167 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1168#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1169 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1170#else
1171 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1172#endif
1173
1174#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1175 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1176#endif
1177#if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1178 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1179#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1180 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1181#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1182 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1183#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1184 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1185#else
1186 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1187#endif
1188
1189#if defined(JSON_HEDLEY_DEPRECATED)
1190 #undef JSON_HEDLEY_DEPRECATED
1191#endif
1192#if defined(JSON_HEDLEY_DEPRECATED_FOR)
1193 #undef JSON_HEDLEY_DEPRECATED_FOR
1194#endif
1195#if \
1196 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1197 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1198 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1199 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1200#elif \
1201 (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1202 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1203 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1204 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1205 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1206 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1207 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1208 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1209 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1210 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1211 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1212 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1213 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1214 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1215#elif defined(__cplusplus) && (__cplusplus >= 201402L)
1216 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1217 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1218#elif \
1219 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1220 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1221 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1222 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1223 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1224 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1225 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1226 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1227 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1228 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1229 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1230 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1231 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1232 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1233 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1234 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1235 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1236 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1237#elif \
1238 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1239 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1240 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1241 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1242 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1243#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1244 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1245 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1246#else
1247 #define JSON_HEDLEY_DEPRECATED(since)
1248 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1249#endif
1250
1251#if defined(JSON_HEDLEY_UNAVAILABLE)
1252 #undef JSON_HEDLEY_UNAVAILABLE
1253#endif
1254#if \
1255 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1256 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1257 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1258 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1259 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1260#else
1261 #define JSON_HEDLEY_UNAVAILABLE(available_since)
1262#endif
1263
1264#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1265 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1266#endif
1267#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1268 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1269#endif
1270#if \
1271 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1272 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1273 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1274 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1275 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1276 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1277 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1278 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1279 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1280 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1281 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1282 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1283 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1284 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1285 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1286 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1287 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1288 #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1289 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1290#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1291 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1292 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1293#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1294 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1295 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1296#elif defined(_Check_return_) /* SAL */
1297 #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1298 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1299#else
1300 #define JSON_HEDLEY_WARN_UNUSED_RESULT
1301 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1302#endif
1303
1304#if defined(JSON_HEDLEY_SENTINEL)
1305 #undef JSON_HEDLEY_SENTINEL
1306#endif
1307#if \
1308 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1309 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1310 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1311 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1312 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1313 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1314#else
1315 #define JSON_HEDLEY_SENTINEL(position)
1316#endif
1317
1318#if defined(JSON_HEDLEY_NO_RETURN)
1319 #undef JSON_HEDLEY_NO_RETURN
1320#endif
1321#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1322 #define JSON_HEDLEY_NO_RETURN __noreturn
1323#elif \
1324 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1325 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1326 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1327#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1328 #define JSON_HEDLEY_NO_RETURN _Noreturn
1329#elif defined(__cplusplus) && (__cplusplus >= 201103L)
1330 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1331#elif \
1332 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1333 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1334 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1335 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1336 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1337 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1338 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1339 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1340 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1341 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1342 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1343 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1344 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1345 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1346 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1347 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1348 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1349 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1350#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1351 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1352#elif \
1353 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1354 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1355 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1356#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1357 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1358#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1359 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1360#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1361 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1362#else
1363 #define JSON_HEDLEY_NO_RETURN
1364#endif
1365
1366#if defined(JSON_HEDLEY_NO_ESCAPE)
1367 #undef JSON_HEDLEY_NO_ESCAPE
1368#endif
1369#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1370 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1371#else
1372 #define JSON_HEDLEY_NO_ESCAPE
1373#endif
1374
1375#if defined(JSON_HEDLEY_UNREACHABLE)
1376 #undef JSON_HEDLEY_UNREACHABLE
1377#endif
1378#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1379 #undef JSON_HEDLEY_UNREACHABLE_RETURN
1380#endif
1381#if defined(JSON_HEDLEY_ASSUME)
1382 #undef JSON_HEDLEY_ASSUME
1383#endif
1384#if \
1385 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1386 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1387 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1388 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1389#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1390 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1391#elif \
1392 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1393 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1394 #if defined(__cplusplus)
1395 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1396 #else
1397 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1398 #endif
1399#endif
1400#if \
1401 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1402 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1403 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1404 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1405 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1406 JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1407 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1408 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1409#elif defined(JSON_HEDLEY_ASSUME)
1410 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1411#endif
1412#if !defined(JSON_HEDLEY_ASSUME)
1413 #if defined(JSON_HEDLEY_UNREACHABLE)
1414 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1415 #else
1416 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1417 #endif
1418#endif
1419#if defined(JSON_HEDLEY_UNREACHABLE)
1420 #if \
1421 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1422 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1423 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1424 #else
1425 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1426 #endif
1427#else
1428 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1429#endif
1430#if !defined(JSON_HEDLEY_UNREACHABLE)
1431 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1432#endif
1433
1435#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1436 #pragma clang diagnostic ignored "-Wpedantic"
1437#endif
1438#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1439 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1440#endif
1441#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1442 #if defined(__clang__)
1443 #pragma clang diagnostic ignored "-Wvariadic-macros"
1444 #elif defined(JSON_HEDLEY_GCC_VERSION)
1445 #pragma GCC diagnostic ignored "-Wvariadic-macros"
1446 #endif
1447#endif
1448#if defined(JSON_HEDLEY_NON_NULL)
1449 #undef JSON_HEDLEY_NON_NULL
1450#endif
1451#if \
1452 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1453 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1454 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1455 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1456 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1457#else
1458 #define JSON_HEDLEY_NON_NULL(...)
1459#endif
1461
1462#if defined(JSON_HEDLEY_PRINTF_FORMAT)
1463 #undef JSON_HEDLEY_PRINTF_FORMAT
1464#endif
1465#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1466 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1467#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1468 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1469#elif \
1470 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1471 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1472 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1473 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1474 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1475 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1476 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1477 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1478 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1479 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1480 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1481 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1482 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1483 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1484 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1485 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1486 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1487 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1488#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1489 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1490#else
1491 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1492#endif
1493
1494#if defined(JSON_HEDLEY_CONSTEXPR)
1495 #undef JSON_HEDLEY_CONSTEXPR
1496#endif
1497#if defined(__cplusplus)
1498 #if __cplusplus >= 201103L
1499 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1500 #endif
1501#endif
1502#if !defined(JSON_HEDLEY_CONSTEXPR)
1503 #define JSON_HEDLEY_CONSTEXPR
1504#endif
1505
1506#if defined(JSON_HEDLEY_PREDICT)
1507 #undef JSON_HEDLEY_PREDICT
1508#endif
1509#if defined(JSON_HEDLEY_LIKELY)
1510 #undef JSON_HEDLEY_LIKELY
1511#endif
1512#if defined(JSON_HEDLEY_UNLIKELY)
1513 #undef JSON_HEDLEY_UNLIKELY
1514#endif
1515#if defined(JSON_HEDLEY_UNPREDICTABLE)
1516 #undef JSON_HEDLEY_UNPREDICTABLE
1517#endif
1518#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1519 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1520#endif
1521#if \
1522 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1523 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1524 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1525# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1526# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1527# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1528# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1529# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1530#elif \
1531 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1532 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1533 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1534 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1535 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1536 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1537 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1538 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1539 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1540 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1541 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1542 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1543 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1544 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1545 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1546 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1547# define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1548 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1549# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1550 (__extension__ ({ \
1551 double hedley_probability_ = (probability); \
1552 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1553 }))
1554# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1555 (__extension__ ({ \
1556 double hedley_probability_ = (probability); \
1557 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1558 }))
1559# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1560# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1561#else
1562# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1563# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1564# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1565# define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1566# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1567#endif
1568#if !defined(JSON_HEDLEY_UNPREDICTABLE)
1569 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1570#endif
1571
1572#if defined(JSON_HEDLEY_MALLOC)
1573 #undef JSON_HEDLEY_MALLOC
1574#endif
1575#if \
1576 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1577 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1578 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1579 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1580 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1581 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1582 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1583 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1584 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1585 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1586 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1587 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1588 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1589 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1590 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1591 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1592 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1593 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1594 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1595#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1596 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1597#elif \
1598 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1599 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1600 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1601#else
1602 #define JSON_HEDLEY_MALLOC
1603#endif
1604
1605#if defined(JSON_HEDLEY_PURE)
1606 #undef JSON_HEDLEY_PURE
1607#endif
1608#if \
1609 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1610 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1611 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1612 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1613 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1614 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1615 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1616 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1617 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1618 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1619 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1620 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1621 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1622 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1623 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1624 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1625 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1626 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1627 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1628# define JSON_HEDLEY_PURE __attribute__((__pure__))
1629#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1630# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1631#elif defined(__cplusplus) && \
1632 ( \
1633 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1634 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1635 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1636 )
1637# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1638#else
1639# define JSON_HEDLEY_PURE
1640#endif
1641
1642#if defined(JSON_HEDLEY_CONST)
1643 #undef JSON_HEDLEY_CONST
1644#endif
1645#if \
1646 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1647 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1648 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1649 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1650 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1651 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1652 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1653 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1654 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1655 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1656 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1657 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1658 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1659 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1660 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1661 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1662 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1663 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1664 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1665 #define JSON_HEDLEY_CONST __attribute__((__const__))
1666#elif \
1667 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1668 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1669#else
1670 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1671#endif
1672
1673#if defined(JSON_HEDLEY_RESTRICT)
1674 #undef JSON_HEDLEY_RESTRICT
1675#endif
1676#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1677 #define JSON_HEDLEY_RESTRICT restrict
1678#elif \
1679 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1680 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1681 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1682 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1683 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1684 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1685 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1686 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1687 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1688 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1689 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1690 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1691 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1692 defined(__clang__) || \
1693 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1694 #define JSON_HEDLEY_RESTRICT __restrict
1695#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1696 #define JSON_HEDLEY_RESTRICT _Restrict
1697#else
1698 #define JSON_HEDLEY_RESTRICT
1699#endif
1700
1701#if defined(JSON_HEDLEY_INLINE)
1702 #undef JSON_HEDLEY_INLINE
1703#endif
1704#if \
1705 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1706 (defined(__cplusplus) && (__cplusplus >= 199711L))
1707 #define JSON_HEDLEY_INLINE inline
1708#elif \
1709 defined(JSON_HEDLEY_GCC_VERSION) || \
1710 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1711 #define JSON_HEDLEY_INLINE __inline__
1712#elif \
1713 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1714 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1715 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1716 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1717 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1718 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1719 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1720 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1721 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1722 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1723 #define JSON_HEDLEY_INLINE __inline
1724#else
1725 #define JSON_HEDLEY_INLINE
1726#endif
1727
1728#if defined(JSON_HEDLEY_ALWAYS_INLINE)
1729 #undef JSON_HEDLEY_ALWAYS_INLINE
1730#endif
1731#if \
1732 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1733 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1734 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1735 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1736 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1737 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1738 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1739 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1740 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1741 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1742 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1743 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1744 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1745 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1746 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1747 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1748 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1749 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1750 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1751# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1752#elif \
1753 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1754 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1755# define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1756#elif defined(__cplusplus) && \
1757 ( \
1758 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1759 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1760 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1761 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1762 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1763 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1764 )
1765# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1766#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1767# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1768#else
1769# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1770#endif
1771
1772#if defined(JSON_HEDLEY_NEVER_INLINE)
1773 #undef JSON_HEDLEY_NEVER_INLINE
1774#endif
1775#if \
1776 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1777 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1778 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1779 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1780 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1781 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1782 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1783 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1784 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1785 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1786 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1787 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1788 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1789 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1790 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1791 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1792 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1793 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1794 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1795 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1796#elif \
1797 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1798 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1799 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1800#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1801 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1802#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1803 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1804#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1805 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1806#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1807 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1808#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1809 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1810#else
1811 #define JSON_HEDLEY_NEVER_INLINE
1812#endif
1813
1814#if defined(JSON_HEDLEY_PRIVATE)
1815 #undef JSON_HEDLEY_PRIVATE
1816#endif
1817#if defined(JSON_HEDLEY_PUBLIC)
1818 #undef JSON_HEDLEY_PUBLIC
1819#endif
1820#if defined(JSON_HEDLEY_IMPORT)
1821 #undef JSON_HEDLEY_IMPORT
1822#endif
1823#if defined(_WIN32) || defined(__CYGWIN__)
1824# define JSON_HEDLEY_PRIVATE
1825# define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1826# define JSON_HEDLEY_IMPORT __declspec(dllimport)
1827#else
1828# if \
1829 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1830 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1831 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1832 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1833 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1834 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1835 ( \
1836 defined(__TI_EABI__) && \
1837 ( \
1838 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1839 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1840 ) \
1841 ) || \
1842 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1843# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1844# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1845# else
1846# define JSON_HEDLEY_PRIVATE
1847# define JSON_HEDLEY_PUBLIC
1848# endif
1849# define JSON_HEDLEY_IMPORT extern
1850#endif
1851
1852#if defined(JSON_HEDLEY_NO_THROW)
1853 #undef JSON_HEDLEY_NO_THROW
1854#endif
1855#if \
1856 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1857 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1858 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1859 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1860 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1861#elif \
1862 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1863 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1864 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1865 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1866#else
1867 #define JSON_HEDLEY_NO_THROW
1868#endif
1869
1870#if defined(JSON_HEDLEY_FALL_THROUGH)
1871 #undef JSON_HEDLEY_FALL_THROUGH
1872#endif
1873#if \
1874 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1875 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
1876 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1877 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1878#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1879 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1880#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1881 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1882#elif defined(__fallthrough) /* SAL */
1883 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1884#else
1885 #define JSON_HEDLEY_FALL_THROUGH
1886#endif
1887
1888#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1889 #undef JSON_HEDLEY_RETURNS_NON_NULL
1890#endif
1891#if \
1892 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1893 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1894 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1895 #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1896#elif defined(_Ret_notnull_) /* SAL */
1897 #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1898#else
1899 #define JSON_HEDLEY_RETURNS_NON_NULL
1900#endif
1901
1902#if defined(JSON_HEDLEY_ARRAY_PARAM)
1903 #undef JSON_HEDLEY_ARRAY_PARAM
1904#endif
1905#if \
1906 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1907 !defined(__STDC_NO_VLA__) && \
1908 !defined(__cplusplus) && \
1909 !defined(JSON_HEDLEY_PGI_VERSION) && \
1910 !defined(JSON_HEDLEY_TINYC_VERSION)
1911 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1912#else
1913 #define JSON_HEDLEY_ARRAY_PARAM(name)
1914#endif
1915
1916#if defined(JSON_HEDLEY_IS_CONSTANT)
1917 #undef JSON_HEDLEY_IS_CONSTANT
1918#endif
1919#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1920 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1921#endif
1922/* JSON_HEDLEY_IS_CONSTEXPR_ is for
1923 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1924#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1925 #undef JSON_HEDLEY_IS_CONSTEXPR_
1926#endif
1927#if \
1928 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1929 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1930 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1931 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1932 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1933 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1934 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1935 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1936 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1937 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1938 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1939#endif
1940#if !defined(__cplusplus)
1941# if \
1942 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1943 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1944 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1945 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1946 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1947 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1948 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1949#if defined(__INTPTR_TYPE__)
1950 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1951#else
1952 #include <stdint.h>
1953 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1954#endif
1955# elif \
1956 ( \
1957 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1958 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1959 !defined(JSON_HEDLEY_PGI_VERSION) && \
1960 !defined(JSON_HEDLEY_IAR_VERSION)) || \
1961 (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1962 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1963 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1964 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1965 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1966#if defined(__INTPTR_TYPE__)
1967 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1968#else
1969 #include <stdint.h>
1970 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1971#endif
1972# elif \
1973 defined(JSON_HEDLEY_GCC_VERSION) || \
1974 defined(JSON_HEDLEY_INTEL_VERSION) || \
1975 defined(JSON_HEDLEY_TINYC_VERSION) || \
1976 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1977 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1978 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1979 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1980 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1981 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1982 defined(__clang__)
1983# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1984 sizeof(void) != \
1985 sizeof(*( \
1986 1 ? \
1987 ((void*) ((expr) * 0L) ) : \
1988((struct { char v[sizeof(void) * 2]; } *) 1) \
1989 ) \
1990 ) \
1991 )
1992# endif
1993#endif
1994#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1995 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1996 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1997 #endif
1998 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1999#else
2000 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2001 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2002 #endif
2003 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2004#endif
2005
2006#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2007 #undef JSON_HEDLEY_BEGIN_C_DECLS
2008#endif
2009#if defined(JSON_HEDLEY_END_C_DECLS)
2010 #undef JSON_HEDLEY_END_C_DECLS
2011#endif
2012#if defined(JSON_HEDLEY_C_DECL)
2013 #undef JSON_HEDLEY_C_DECL
2014#endif
2015#if defined(__cplusplus)
2016 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2017 #define JSON_HEDLEY_END_C_DECLS }
2018 #define JSON_HEDLEY_C_DECL extern "C"
2019#else
2020 #define JSON_HEDLEY_BEGIN_C_DECLS
2021 #define JSON_HEDLEY_END_C_DECLS
2022 #define JSON_HEDLEY_C_DECL
2023#endif
2024
2025#if defined(JSON_HEDLEY_STATIC_ASSERT)
2026 #undef JSON_HEDLEY_STATIC_ASSERT
2027#endif
2028#if \
2029 !defined(__cplusplus) && ( \
2030 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2031 (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2032 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2033 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2034 defined(_Static_assert) \
2035 )
2036# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2037#elif \
2038 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2039 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2040 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2041# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2042#else
2043# define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2044#endif
2045
2046#if defined(JSON_HEDLEY_NULL)
2047 #undef JSON_HEDLEY_NULL
2048#endif
2049#if defined(__cplusplus)
2050 #if __cplusplus >= 201103L
2051 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2052 #elif defined(NULL)
2053 #define JSON_HEDLEY_NULL NULL
2054 #else
2055 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2056 #endif
2057#elif defined(NULL)
2058 #define JSON_HEDLEY_NULL NULL
2059#else
2060 #define JSON_HEDLEY_NULL ((void*) 0)
2061#endif
2062
2063#if defined(JSON_HEDLEY_MESSAGE)
2064 #undef JSON_HEDLEY_MESSAGE
2065#endif
2066#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2067# define JSON_HEDLEY_MESSAGE(msg) \
2068 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2069 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2070 JSON_HEDLEY_PRAGMA(message msg) \
2071 JSON_HEDLEY_DIAGNOSTIC_POP
2072#elif \
2073 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2074 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2075# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2076#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2077# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2078#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2079# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2080#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2081# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2082#else
2083# define JSON_HEDLEY_MESSAGE(msg)
2084#endif
2085
2086#if defined(JSON_HEDLEY_WARNING)
2087 #undef JSON_HEDLEY_WARNING
2088#endif
2089#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2090# define JSON_HEDLEY_WARNING(msg) \
2091 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2092 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2093 JSON_HEDLEY_PRAGMA(clang warning msg) \
2094 JSON_HEDLEY_DIAGNOSTIC_POP
2095#elif \
2096 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2097 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2098 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2099# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2100#elif \
2101 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2102 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2103# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2104#else
2105# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2106#endif
2107
2108#if defined(JSON_HEDLEY_REQUIRE)
2109 #undef JSON_HEDLEY_REQUIRE
2110#endif
2111#if defined(JSON_HEDLEY_REQUIRE_MSG)
2112 #undef JSON_HEDLEY_REQUIRE_MSG
2113#endif
2114#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2115# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2116# define JSON_HEDLEY_REQUIRE(expr) \
2117 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2118 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2119 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2120 JSON_HEDLEY_DIAGNOSTIC_POP
2121# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2122 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2123 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2124 __attribute__((diagnose_if(!(expr), msg, "error"))) \
2125 JSON_HEDLEY_DIAGNOSTIC_POP
2126# else
2127# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2128# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2129# endif
2130#else
2131# define JSON_HEDLEY_REQUIRE(expr)
2132# define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2133#endif
2134
2135#if defined(JSON_HEDLEY_FLAGS)
2136 #undef JSON_HEDLEY_FLAGS
2137#endif
2138#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2139 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2140#else
2141 #define JSON_HEDLEY_FLAGS
2142#endif
2143
2144#if defined(JSON_HEDLEY_FLAGS_CAST)
2145 #undef JSON_HEDLEY_FLAGS_CAST
2146#endif
2147#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2148# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2149 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2150 _Pragma("warning(disable:188)") \
2151 ((T) (expr)); \
2152 JSON_HEDLEY_DIAGNOSTIC_POP \
2153 }))
2154#else
2155# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2156#endif
2157
2158#if defined(JSON_HEDLEY_EMPTY_BASES)
2159 #undef JSON_HEDLEY_EMPTY_BASES
2160#endif
2161#if \
2162 (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2163 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2164 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2165#else
2166 #define JSON_HEDLEY_EMPTY_BASES
2167#endif
2168
2169/* Remaining macros are deprecated. */
2170
2171#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2172 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2173#endif
2174#if defined(__clang__)
2175 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2176#else
2177 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2178#endif
2179
2180#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2181 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2182#endif
2183#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2184
2185#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2186 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2187#endif
2188#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2189
2190#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2191 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2192#endif
2193#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2194
2195#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2196 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2197#endif
2198#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2199
2200#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2201 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2202#endif
2203#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2204
2205#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2206 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2207#endif
2208#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2209
2210#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2211 #undef JSON_HEDLEY_CLANG_HAS_WARNING
2212#endif
2213#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2214
2215#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2216
2217// #include <nlohmann/detail/meta/detected.hpp>
2218
2219
2220#include <type_traits>
2221
2222// #include <nlohmann/detail/meta/void_t.hpp>
2223
2224
2225namespace nlohmann
2226{
2227namespace detail
2228{
2229template<typename ...Ts> struct make_void
2230{
2231 using type = void;
2232};
2233template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2234} // namespace detail
2235} // namespace nlohmann
2236
2237
2238// https://en.cppreference.com/w/cpp/experimental/is_detected
2239namespace nlohmann
2240{
2241namespace detail
2242{
2244{
2245 nonesuch() = delete;
2246 ~nonesuch() = delete;
2247 nonesuch(nonesuch const&) = delete;
2248 nonesuch(nonesuch const&&) = delete;
2249 void operator=(nonesuch const&) = delete;
2250 void operator=(nonesuch&&) = delete;
2251};
2252
2253template<class Default,
2254 class AlwaysVoid,
2255 template<class...> class Op,
2256 class... Args>
2258{
2259 using value_t = std::false_type;
2260 using type = Default;
2261};
2262
2263template<class Default, template<class...> class Op, class... Args>
2264struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2265{
2266 using value_t = std::true_type;
2267 using type = Op<Args...>;
2268};
2269
2270template<template<class...> class Op, class... Args>
2271using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2272
2273template<template<class...> class Op, class... Args>
2274struct is_detected_lazy : is_detected<Op, Args...> { };
2275
2276template<template<class...> class Op, class... Args>
2277using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2278
2279template<class Default, template<class...> class Op, class... Args>
2280using detected_or = detector<Default, void, Op, Args...>;
2281
2282template<class Default, template<class...> class Op, class... Args>
2283using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2284
2285template<class Expected, template<class...> class Op, class... Args>
2286using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2287
2288template<class To, template<class...> class Op, class... Args>
2290 std::is_convertible<detected_t<Op, Args...>, To>;
2291} // namespace detail
2292} // namespace nlohmann
2293
2294
2295// This file contains all internal macro definitions
2296// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2297
2298// exclude unsupported compilers
2299#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2300 #if defined(__clang__)
2301 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2302 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2303 #endif
2304 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2305 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2306 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2307 #endif
2308 #endif
2309#endif
2310
2311// C++ language standard detection
2312// if the user manually specified the used c++ version this is skipped
2313#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2314 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2315 #define JSON_HAS_CPP_20
2316 #define JSON_HAS_CPP_17
2317 #define JSON_HAS_CPP_14
2318 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2319 #define JSON_HAS_CPP_17
2320 #define JSON_HAS_CPP_14
2321 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2322 #define JSON_HAS_CPP_14
2323 #endif
2324 // the cpp 11 flag is always specified because it is the minimal required version
2325 #define JSON_HAS_CPP_11
2326#endif
2327
2328// disable documentation warnings on clang
2329#if defined(__clang__)
2330 #pragma clang diagnostic push
2331 #pragma clang diagnostic ignored "-Wdocumentation"
2332 #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2333#endif
2334
2335// allow to disable exceptions
2336#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2337 #define JSON_THROW(exception) throw exception
2338 #define JSON_TRY try
2339 #define JSON_CATCH(exception) catch(exception)
2340 #define JSON_INTERNAL_CATCH(exception) catch(exception)
2341#else
2342 #include <cstdlib>
2343 #define JSON_THROW(exception) std::abort()
2344 #define JSON_TRY if(true)
2345 #define JSON_CATCH(exception) if(false)
2346 #define JSON_INTERNAL_CATCH(exception) if(false)
2347#endif
2348
2349// override exception macros
2350#if defined(JSON_THROW_USER)
2351 #undef JSON_THROW
2352 #define JSON_THROW JSON_THROW_USER
2353#endif
2354#if defined(JSON_TRY_USER)
2355 #undef JSON_TRY
2356 #define JSON_TRY JSON_TRY_USER
2357#endif
2358#if defined(JSON_CATCH_USER)
2359 #undef JSON_CATCH
2360 #define JSON_CATCH JSON_CATCH_USER
2361 #undef JSON_INTERNAL_CATCH
2362 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2363#endif
2364#if defined(JSON_INTERNAL_CATCH_USER)
2365 #undef JSON_INTERNAL_CATCH
2366 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2367#endif
2368
2369// allow to override assert
2370#if !defined(JSON_ASSERT)
2371 #include <cassert> // assert
2372 #define JSON_ASSERT(x) assert(x)
2373#endif
2374
2375// allow to access some private functions (needed by the test suite)
2376#if defined(JSON_TESTS_PRIVATE)
2377 #define JSON_PRIVATE_UNLESS_TESTED public
2378#else
2379 #define JSON_PRIVATE_UNLESS_TESTED private
2380#endif
2381
2387#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2388 template<typename BasicJsonType> \
2389 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2390 { \
2391 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2392 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2393 auto it = std::find_if(std::begin(m), std::end(m), \
2394 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2395 { \
2396 return ej_pair.first == e; \
2397 }); \
2398 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2399 } \
2400 template<typename BasicJsonType> \
2401 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2402 { \
2403 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2404 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2405 auto it = std::find_if(std::begin(m), std::end(m), \
2406 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2407 { \
2408 return ej_pair.second == j; \
2409 }); \
2410 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2411 }
2412
2413// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2414// may be removed in the future once the class is split.
2415
2416#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2417 template<template<typename, typename, typename...> class ObjectType, \
2418 template<typename, typename...> class ArrayType, \
2419 class StringType, class BooleanType, class NumberIntegerType, \
2420 class NumberUnsignedType, class NumberFloatType, \
2421 template<typename> class AllocatorType, \
2422 template<typename, typename = void> class JSONSerializer, \
2423 class BinaryType>
2424
2425#define NLOHMANN_BASIC_JSON_TPL \
2426 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2427 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2428 AllocatorType, JSONSerializer, BinaryType>
2429
2430// Macros to simplify conversion from/to types
2431
2432#define NLOHMANN_JSON_EXPAND( x ) x
2433#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2434#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2435 NLOHMANN_JSON_PASTE64, \
2436 NLOHMANN_JSON_PASTE63, \
2437 NLOHMANN_JSON_PASTE62, \
2438 NLOHMANN_JSON_PASTE61, \
2439 NLOHMANN_JSON_PASTE60, \
2440 NLOHMANN_JSON_PASTE59, \
2441 NLOHMANN_JSON_PASTE58, \
2442 NLOHMANN_JSON_PASTE57, \
2443 NLOHMANN_JSON_PASTE56, \
2444 NLOHMANN_JSON_PASTE55, \
2445 NLOHMANN_JSON_PASTE54, \
2446 NLOHMANN_JSON_PASTE53, \
2447 NLOHMANN_JSON_PASTE52, \
2448 NLOHMANN_JSON_PASTE51, \
2449 NLOHMANN_JSON_PASTE50, \
2450 NLOHMANN_JSON_PASTE49, \
2451 NLOHMANN_JSON_PASTE48, \
2452 NLOHMANN_JSON_PASTE47, \
2453 NLOHMANN_JSON_PASTE46, \
2454 NLOHMANN_JSON_PASTE45, \
2455 NLOHMANN_JSON_PASTE44, \
2456 NLOHMANN_JSON_PASTE43, \
2457 NLOHMANN_JSON_PASTE42, \
2458 NLOHMANN_JSON_PASTE41, \
2459 NLOHMANN_JSON_PASTE40, \
2460 NLOHMANN_JSON_PASTE39, \
2461 NLOHMANN_JSON_PASTE38, \
2462 NLOHMANN_JSON_PASTE37, \
2463 NLOHMANN_JSON_PASTE36, \
2464 NLOHMANN_JSON_PASTE35, \
2465 NLOHMANN_JSON_PASTE34, \
2466 NLOHMANN_JSON_PASTE33, \
2467 NLOHMANN_JSON_PASTE32, \
2468 NLOHMANN_JSON_PASTE31, \
2469 NLOHMANN_JSON_PASTE30, \
2470 NLOHMANN_JSON_PASTE29, \
2471 NLOHMANN_JSON_PASTE28, \
2472 NLOHMANN_JSON_PASTE27, \
2473 NLOHMANN_JSON_PASTE26, \
2474 NLOHMANN_JSON_PASTE25, \
2475 NLOHMANN_JSON_PASTE24, \
2476 NLOHMANN_JSON_PASTE23, \
2477 NLOHMANN_JSON_PASTE22, \
2478 NLOHMANN_JSON_PASTE21, \
2479 NLOHMANN_JSON_PASTE20, \
2480 NLOHMANN_JSON_PASTE19, \
2481 NLOHMANN_JSON_PASTE18, \
2482 NLOHMANN_JSON_PASTE17, \
2483 NLOHMANN_JSON_PASTE16, \
2484 NLOHMANN_JSON_PASTE15, \
2485 NLOHMANN_JSON_PASTE14, \
2486 NLOHMANN_JSON_PASTE13, \
2487 NLOHMANN_JSON_PASTE12, \
2488 NLOHMANN_JSON_PASTE11, \
2489 NLOHMANN_JSON_PASTE10, \
2490 NLOHMANN_JSON_PASTE9, \
2491 NLOHMANN_JSON_PASTE8, \
2492 NLOHMANN_JSON_PASTE7, \
2493 NLOHMANN_JSON_PASTE6, \
2494 NLOHMANN_JSON_PASTE5, \
2495 NLOHMANN_JSON_PASTE4, \
2496 NLOHMANN_JSON_PASTE3, \
2497 NLOHMANN_JSON_PASTE2, \
2498 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2499#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2500#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2501#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2502#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2503#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2504#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2505#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2506#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2507#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2508#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2509#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2510#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2511#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2512#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2513#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2514#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2515#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2516#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2517#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2518#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2519#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2520#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2521#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2522#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2523#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2524#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2525#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2526#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2527#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2528#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2529#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2530#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2531#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2532#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2533#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2534#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2535#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2536#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2537#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2538#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2539#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2540#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2541#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2542#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2543#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2544#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2545#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2546#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2547#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2548#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2549#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2550#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2551#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2552#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2553#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2554#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2555#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2556#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2557#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2558#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2559#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2560#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2561#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2562
2563#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2564#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2565
2571#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2572 friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2573 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2574
2580#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2581 inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2582 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2583
2584
2585// inspired from https://stackoverflow.com/a/26745591
2586// allows to call any std function as if (e.g. with begin):
2587// using std::begin; begin(x);
2588//
2589// it allows using the detected idiom to retrieve the return type
2590// of such an expression
2591#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2592 namespace detail { \
2593 using std::std_name; \
2594 \
2595 template<typename... T> \
2596 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2597 } \
2598 \
2599 namespace detail2 { \
2600 struct std_name##_tag \
2601 { \
2602 }; \
2603 \
2604 template<typename... T> \
2605 std_name##_tag std_name(T&&...); \
2606 \
2607 template<typename... T> \
2608 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2609 \
2610 template<typename... T> \
2611 struct would_call_std_##std_name \
2612 { \
2613 static constexpr auto const value = ::nlohmann::detail:: \
2614 is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2615 }; \
2616 } /* namespace detail2 */ \
2617 \
2618 template<typename... T> \
2619 struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2620 { \
2621 }
2622
2623#ifndef JSON_USE_IMPLICIT_CONVERSIONS
2624 #define JSON_USE_IMPLICIT_CONVERSIONS 1
2625#endif
2626
2627#if JSON_USE_IMPLICIT_CONVERSIONS
2628 #define JSON_EXPLICIT
2629#else
2630 #define JSON_EXPLICIT explicit
2631#endif
2632
2633#ifndef JSON_DIAGNOSTICS
2634 #define JSON_DIAGNOSTICS 0
2635#endif
2636
2637
2638namespace nlohmann
2639{
2640namespace detail
2641{
2642
2656inline void replace_substring(std::string& s, const std::string& f,
2657 const std::string& t)
2658{
2659 JSON_ASSERT(!f.empty());
2660 for (auto pos = s.find(f); // find first occurrence of f
2661 pos != std::string::npos; // make sure f was found
2662 s.replace(pos, f.size(), t), // replace with t, and
2663 pos = s.find(f, pos + t.size())) // find next occurrence of f
2664 {}
2665}
2666
2674inline std::string escape(std::string s)
2675{
2676 replace_substring(s, "~", "~0");
2677 replace_substring(s, "/", "~1");
2678 return s;
2679}
2680
2688static void unescape(std::string& s)
2689{
2690 replace_substring(s, "~1", "/");
2691 replace_substring(s, "~0", "~");
2692}
2693
2694} // namespace detail
2695} // namespace nlohmann
2696
2697// #include <nlohmann/detail/input/position_t.hpp>
2698
2699
2700#include <cstddef> // size_t
2701
2702namespace nlohmann
2703{
2704namespace detail
2705{
2708{
2710 std::size_t chars_read_total = 0;
2714 std::size_t lines_read = 0;
2715
2717 constexpr operator size_t() const
2718 {
2719 return chars_read_total;
2720 }
2721};
2722
2723} // namespace detail
2724} // namespace nlohmann
2725
2726// #include <nlohmann/detail/macro_scope.hpp>
2727
2728
2729namespace nlohmann
2730{
2731namespace detail
2732{
2734// exceptions //
2736
2765class exception : public std::exception
2766{
2767 public:
2769 const char* what() const noexcept override
2770 {
2771 return m.what();
2772 }
2773
2775 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
2776
2777 protected:
2779 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
2780
2781 static std::string name(const std::string& ename, int id_)
2782 {
2783 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2784 }
2785
2786 template<typename BasicJsonType>
2787 static std::string diagnostics(const BasicJsonType& leaf_element)
2788 {
2789#if JSON_DIAGNOSTICS
2790 std::vector<std::string> tokens;
2791 for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
2792 {
2793 switch (current->m_parent->type())
2794 {
2795 case value_t::array:
2796 {
2797 for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
2798 {
2799 if (&current->m_parent->m_value.array->operator[](i) == current)
2800 {
2801 tokens.emplace_back(std::to_string(i));
2802 break;
2803 }
2804 }
2805 break;
2806 }
2807
2808 case value_t::object:
2809 {
2810 for (const auto& element : *current->m_parent->m_value.object)
2811 {
2812 if (&element.second == current)
2813 {
2814 tokens.emplace_back(element.first.c_str());
2815 break;
2816 }
2817 }
2818 break;
2819 }
2820
2821 case value_t::null: // LCOV_EXCL_LINE
2822 case value_t::string: // LCOV_EXCL_LINE
2823 case value_t::boolean: // LCOV_EXCL_LINE
2824 case value_t::number_integer: // LCOV_EXCL_LINE
2825 case value_t::number_unsigned: // LCOV_EXCL_LINE
2826 case value_t::number_float: // LCOV_EXCL_LINE
2827 case value_t::binary: // LCOV_EXCL_LINE
2828 case value_t::discarded: // LCOV_EXCL_LINE
2829 default: // LCOV_EXCL_LINE
2830 break; // LCOV_EXCL_LINE
2831 }
2832 }
2833
2834 if (tokens.empty())
2835 {
2836 return "";
2837 }
2838
2839 return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
2840 [](const std::string & a, const std::string & b)
2841 {
2842 return a + "/" + detail::escape(b);
2843 }) + ") ";
2844#else
2845 static_cast<void>(leaf_element);
2846 return "";
2847#endif
2848 }
2849
2850 private:
2852 std::runtime_error m;
2853};
2854
2901{
2902 public:
2912 template<typename BasicJsonType>
2913 static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)
2914 {
2915 std::string w = exception::name("parse_error", id_) + "parse error" +
2916 position_string(pos) + ": " + exception::diagnostics(context) + what_arg;
2917 return {id_, pos.chars_read_total, w.c_str()};
2918 }
2919
2920 template<typename BasicJsonType>
2921 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)
2922 {
2923 std::string w = exception::name("parse_error", id_) + "parse error" +
2924 (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2925 ": " + exception::diagnostics(context) + what_arg;
2926 return {id_, byte_, w.c_str()};
2927 }
2928
2938 const std::size_t byte;
2939
2940 private:
2941 parse_error(int id_, std::size_t byte_, const char* what_arg)
2942 : exception(id_, what_arg), byte(byte_) {}
2943
2944 static std::string position_string(const position_t& pos)
2945 {
2946 return " at line " + std::to_string(pos.lines_read + 1) +
2947 ", column " + std::to_string(pos.chars_read_current_line);
2948 }
2949};
2950
2989{
2990 public:
2991 template<typename BasicJsonType>
2992 static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
2993 {
2994 std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
2995 return {id_, w.c_str()};
2996 }
2997
2998 private:
3000 invalid_iterator(int id_, const char* what_arg)
3001 : exception(id_, what_arg) {}
3002};
3003
3043class type_error : public exception
3044{
3045 public:
3046 template<typename BasicJsonType>
3047 static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3048 {
3049 std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
3050 return {id_, w.c_str()};
3051 }
3052
3053 private:
3055 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3056};
3057
3092{
3093 public:
3094 template<typename BasicJsonType>
3095 static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
3096 {
3097 std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
3098 return {id_, w.c_str()};
3099 }
3100
3101 private:
3103 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
3104};
3105
3131{
3132 public:
3133 template<typename BasicJsonType>
3134 static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3135 {
3136 std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
3137 return {id_, w.c_str()};
3138 }
3139
3140 private:
3142 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3143};
3144} // namespace detail
3145} // namespace nlohmann
3146
3147// #include <nlohmann/detail/macro_scope.hpp>
3148
3149// #include <nlohmann/detail/meta/cpp_future.hpp>
3150
3151
3152#include <cstddef> // size_t
3153#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3154#include <utility> // index_sequence, make_index_sequence, index_sequence_for
3155
3156// #include <nlohmann/detail/macro_scope.hpp>
3157
3158
3159namespace nlohmann
3160{
3161namespace detail
3162{
3163
3164template<typename T>
3165using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3166
3167#ifdef JSON_HAS_CPP_14
3168
3169// the following utilities are natively available in C++14
3170using std::enable_if_t;
3171using std::index_sequence;
3172using std::make_index_sequence;
3173using std::index_sequence_for;
3174
3175#else
3176
3177// alias templates to reduce boilerplate
3178template<bool B, typename T = void>
3179using enable_if_t = typename std::enable_if<B, T>::type;
3180
3181// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3182// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3183
3185
3186// integer_sequence
3187//
3188// Class template representing a compile-time integer sequence. An instantiation
3189// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3190// type through its template arguments (which is a common need when
3191// working with C++11 variadic templates). `absl::integer_sequence` is designed
3192// to be a drop-in replacement for C++14's `std::integer_sequence`.
3193//
3194// Example:
3195//
3196// template< class T, T... Ints >
3197// void user_function(integer_sequence<T, Ints...>);
3198//
3199// int main()
3200// {
3201// // user_function's `T` will be deduced to `int` and `Ints...`
3202// // will be deduced to `0, 1, 2, 3, 4`.
3203// user_function(make_integer_sequence<int, 5>());
3204// }
3205template <typename T, T... Ints>
3207{
3208 using value_type = T;
3209 static constexpr std::size_t size() noexcept
3210 {
3211 return sizeof...(Ints);
3212 }
3213};
3214
3215// index_sequence
3216//
3217// A helper template for an `integer_sequence` of `size_t`,
3218// `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3219// `std::index_sequence`.
3220template <size_t... Ints>
3221using index_sequence = integer_sequence<size_t, Ints...>;
3222
3223namespace utility_internal
3224{
3225
3226template <typename Seq, size_t SeqSize, size_t Rem>
3227struct Extend;
3228
3229// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3230template <typename T, T... Ints, size_t SeqSize>
3231struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3232{
3233 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3234};
3235
3236template <typename T, T... Ints, size_t SeqSize>
3237struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3238{
3239 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3240};
3241
3242// Recursion helper for 'make_integer_sequence<T, N>'.
3243// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3244template <typename T, size_t N>
3245struct Gen
3246{
3247 using type =
3248 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3249};
3250
3251template <typename T>
3252struct Gen<T, 0>
3253{
3255};
3256
3257} // namespace utility_internal
3258
3259// Compile-time sequences of integers
3260
3261// make_integer_sequence
3262//
3263// This template alias is equivalent to
3264// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3265// replacement for C++14's `std::make_integer_sequence`.
3266template <typename T, T N>
3268
3269// make_index_sequence
3270//
3271// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3272// and is designed to be a drop-in replacement for C++14's
3273// `std::make_index_sequence`.
3274template <size_t N>
3276
3277// index_sequence_for
3278//
3279// Converts a typename pack into an index sequence of the same length, and
3280// is designed to be a drop-in replacement for C++14's
3281// `std::index_sequence_for()`
3282template <typename... Ts>
3284
3286
3287#endif
3288
3289// dispatch utility (taken from ranges-v3)
3290template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3291template<> struct priority_tag<0> {};
3292
3293// taken from ranges-v3
3294template<typename T>
3296{
3297 static constexpr T value{};
3298};
3299
3300template<typename T>
3301constexpr T static_const<T>::value;
3302
3303} // namespace detail
3304} // namespace nlohmann
3305
3306// #include <nlohmann/detail/meta/identity_tag.hpp>
3307
3308
3309namespace nlohmann
3310{
3311namespace detail
3312{
3313// dispatching helper struct
3314template <class T> struct identity_tag {};
3315} // namespace detail
3316} // namespace nlohmann
3317
3318// #include <nlohmann/detail/meta/type_traits.hpp>
3319
3320
3321#include <limits> // numeric_limits
3322#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3323#include <utility> // declval
3324#include <tuple> // tuple
3325
3326// #include <nlohmann/detail/macro_scope.hpp>
3327
3328
3329// #include <nlohmann/detail/iterators/iterator_traits.hpp>
3330
3331
3332#include <iterator> // random_access_iterator_tag
3333
3334// #include <nlohmann/detail/meta/void_t.hpp>
3335
3336// #include <nlohmann/detail/meta/cpp_future.hpp>
3337
3338
3339namespace nlohmann
3340{
3341namespace detail
3342{
3343template<typename It, typename = void>
3345
3346template<typename It>
3348 It,
3349 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3350 typename It::reference, typename It::iterator_category >>
3351{
3352 using difference_type = typename It::difference_type;
3353 using value_type = typename It::value_type;
3354 using pointer = typename It::pointer;
3355 using reference = typename It::reference;
3356 using iterator_category = typename It::iterator_category;
3357};
3358
3359// This is required as some compilers implement std::iterator_traits in a way that
3360// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3361template<typename T, typename = void>
3363{
3364};
3365
3366template<typename T>
3367struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3368 : iterator_types<T>
3369{
3370};
3371
3372template<typename T>
3374{
3375 using iterator_category = std::random_access_iterator_tag;
3376 using value_type = T;
3377 using difference_type = ptrdiff_t;
3378 using pointer = T*;
3379 using reference = T&;
3380};
3381} // namespace detail
3382} // namespace nlohmann
3383
3384// #include <nlohmann/detail/meta/call_std/begin.hpp>
3385
3386
3387// #include <nlohmann/detail/macro_scope.hpp>
3388
3389
3390namespace nlohmann
3391{
3393} // namespace nlohmann
3394
3395// #include <nlohmann/detail/meta/call_std/end.hpp>
3396
3397
3398// #include <nlohmann/detail/macro_scope.hpp>
3399
3400
3401namespace nlohmann
3402{
3404} // namespace nlohmann
3405
3406// #include <nlohmann/detail/meta/cpp_future.hpp>
3407
3408// #include <nlohmann/detail/meta/detected.hpp>
3409
3410// #include <nlohmann/json_fwd.hpp>
3411#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3412#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3413
3414#include <cstdint> // int64_t, uint64_t
3415#include <map> // map
3416#include <memory> // allocator
3417#include <string> // string
3418#include <vector> // vector
3419
3425namespace nlohmann
3426{
3434template<typename T = void, typename SFINAE = void>
3435struct adl_serializer;
3436
3437template<template<typename U, typename V, typename... Args> class ObjectType =
3438 std::map,
3439 template<typename U, typename... Args> class ArrayType = std::vector,
3440 class StringType = std::string, class BooleanType = bool,
3441 class NumberIntegerType = std::int64_t,
3442 class NumberUnsignedType = std::uint64_t,
3443 class NumberFloatType = double,
3444 template<typename U> class AllocatorType = std::allocator,
3445 template<typename T, typename SFINAE = void> class JSONSerializer =
3446 adl_serializer,
3447 class BinaryType = std::vector<std::uint8_t>>
3448class basic_json;
3449
3461template<typename BasicJsonType>
3462class json_pointer;
3463
3473
3474template<class Key, class T, class IgnoredLess, class Allocator>
3475struct ordered_map;
3476
3485
3486} // namespace nlohmann
3487
3488#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3489
3490
3491namespace nlohmann
3492{
3501namespace detail
3502{
3504// helpers //
3506
3507// Note to maintainers:
3508//
3509// Every trait in this file expects a non CV-qualified type.
3510// The only exceptions are in the 'aliases for detected' section
3511// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3512//
3513// In this case, T has to be properly CV-qualified to constraint the function arguments
3514// (e.g. to_json(BasicJsonType&, const T&))
3515
3516template<typename> struct is_basic_json : std::false_type {};
3517
3519struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3520
3522// json_ref helpers //
3524
3525template<typename>
3526class json_ref;
3527
3528template<typename>
3529struct is_json_ref : std::false_type {};
3530
3531template<typename T>
3532struct is_json_ref<json_ref<T>> : std::true_type {};
3533
3535// aliases for detected //
3537
3538template<typename T>
3539using mapped_type_t = typename T::mapped_type;
3540
3541template<typename T>
3542using key_type_t = typename T::key_type;
3543
3544template<typename T>
3545using value_type_t = typename T::value_type;
3546
3547template<typename T>
3548using difference_type_t = typename T::difference_type;
3549
3550template<typename T>
3551using pointer_t = typename T::pointer;
3552
3553template<typename T>
3554using reference_t = typename T::reference;
3555
3556template<typename T>
3557using iterator_category_t = typename T::iterator_category;
3558
3559template<typename T, typename... Args>
3560using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3561
3562template<typename T, typename... Args>
3563using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3564
3565template<typename T, typename U>
3566using get_template_function = decltype(std::declval<T>().template get<U>());
3567
3568// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3569template<typename BasicJsonType, typename T, typename = void>
3570struct has_from_json : std::false_type {};
3571
3572// trait checking if j.get<T> is valid
3573// use this trait instead of std::is_constructible or std::is_convertible,
3574// both rely on, or make use of implicit conversions, and thus fail when T
3575// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3576template <typename BasicJsonType, typename T>
3578{
3580};
3581
3582template<typename BasicJsonType, typename T>
3583struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3584{
3585 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3586
3587 static constexpr bool value =
3589 const BasicJsonType&, T&>::value;
3590};
3591
3592// This trait checks if JSONSerializer<T>::from_json(json const&) exists
3593// this overload is used for non-default-constructible user-defined-types
3594template<typename BasicJsonType, typename T, typename = void>
3595struct has_non_default_from_json : std::false_type {};
3596
3597template<typename BasicJsonType, typename T>
3598struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3599{
3600 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3601
3602 static constexpr bool value =
3604 const BasicJsonType&>::value;
3605};
3606
3607// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3608// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3609template<typename BasicJsonType, typename T, typename = void>
3610struct has_to_json : std::false_type {};
3611
3612template<typename BasicJsonType, typename T>
3613struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3614{
3615 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3616
3617 static constexpr bool value =
3618 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3619 T>::value;
3620};
3621
3622
3624// is_ functions //
3626
3627// https://en.cppreference.com/w/cpp/types/conjunction
3628template<class...> struct conjunction : std::true_type { };
3629template<class B1> struct conjunction<B1> : B1 { };
3630template<class B1, class... Bn>
3631struct conjunction<B1, Bn...>
3632: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3633
3634// https://en.cppreference.com/w/cpp/types/negation
3635template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3636
3637// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3638// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3639// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3640template <typename T>
3641struct is_default_constructible : std::is_default_constructible<T> {};
3642
3643template <typename T1, typename T2>
3644struct is_default_constructible<std::pair<T1, T2>>
3645 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3646
3647template <typename T1, typename T2>
3648struct is_default_constructible<const std::pair<T1, T2>>
3649 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3650
3651template <typename... Ts>
3652struct is_default_constructible<std::tuple<Ts...>>
3653 : conjunction<is_default_constructible<Ts>...> {};
3654
3655template <typename... Ts>
3656struct is_default_constructible<const std::tuple<Ts...>>
3657 : conjunction<is_default_constructible<Ts>...> {};
3658
3659
3660template <typename T, typename... Args>
3661struct is_constructible : std::is_constructible<T, Args...> {};
3662
3663template <typename T1, typename T2>
3664struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3665
3666template <typename T1, typename T2>
3667struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3668
3669template <typename... Ts>
3670struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3671
3672template <typename... Ts>
3673struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3674
3675
3676template<typename T, typename = void>
3677struct is_iterator_traits : std::false_type {};
3678
3679template<typename T>
3681{
3682 private:
3684
3685 public:
3686 static constexpr auto value =
3692};
3693
3694template<typename T>
3696{
3697 private:
3698 using t_ref = typename std::add_lvalue_reference<T>::type;
3699
3702
3703 // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3704 // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3705 // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3706 static constexpr auto is_iterator_begin =
3708
3709 public:
3710 static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
3711};
3712
3713template<typename R>
3714using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3715
3716template<typename T>
3718
3719// The following implementation of is_complete_type is taken from
3720// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3721// and is written by Xiang Fan who agreed to using it in this library.
3722
3723template<typename T, typename = void>
3724struct is_complete_type : std::false_type {};
3725
3726template<typename T>
3727struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3728
3729template<typename BasicJsonType, typename CompatibleObjectType,
3730 typename = void>
3731struct is_compatible_object_type_impl : std::false_type {};
3732
3733template<typename BasicJsonType, typename CompatibleObjectType>
3735 BasicJsonType, CompatibleObjectType,
3736 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3737 is_detected<key_type_t, CompatibleObjectType>::value >>
3738{
3739 using object_t = typename BasicJsonType::object_t;
3740
3741 // macOS's is_constructible does not play well with nonesuch...
3742 static constexpr bool value =
3743 is_constructible<typename object_t::key_type,
3744 typename CompatibleObjectType::key_type>::value &&
3745 is_constructible<typename object_t::mapped_type,
3746 typename CompatibleObjectType::mapped_type>::value;
3747};
3748
3749template<typename BasicJsonType, typename CompatibleObjectType>
3751 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3752
3753template<typename BasicJsonType, typename ConstructibleObjectType,
3754 typename = void>
3755struct is_constructible_object_type_impl : std::false_type {};
3756
3757template<typename BasicJsonType, typename ConstructibleObjectType>
3759 BasicJsonType, ConstructibleObjectType,
3760 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3761 is_detected<key_type_t, ConstructibleObjectType>::value >>
3762{
3763 using object_t = typename BasicJsonType::object_t;
3764
3765 static constexpr bool value =
3767 (std::is_move_assignable<ConstructibleObjectType>::value ||
3768 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3769 (is_constructible<typename ConstructibleObjectType::key_type,
3770 typename object_t::key_type>::value &&
3771 std::is_same <
3772 typename object_t::mapped_type,
3773 typename ConstructibleObjectType::mapped_type >::value)) ||
3774 (has_from_json<BasicJsonType,
3775 typename ConstructibleObjectType::mapped_type>::value ||
3777 BasicJsonType,
3778 typename ConstructibleObjectType::mapped_type >::value);
3779};
3780
3781template<typename BasicJsonType, typename ConstructibleObjectType>
3783 : is_constructible_object_type_impl<BasicJsonType,
3784 ConstructibleObjectType> {};
3785
3786template<typename BasicJsonType, typename CompatibleStringType>
3788{
3789 static constexpr auto value =
3791};
3792
3793template<typename BasicJsonType, typename ConstructibleStringType>
3795{
3796 static constexpr auto value =
3797 is_constructible<ConstructibleStringType,
3798 typename BasicJsonType::string_t>::value;
3799};
3800
3801template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3802struct is_compatible_array_type_impl : std::false_type {};
3803
3804template<typename BasicJsonType, typename CompatibleArrayType>
3806 BasicJsonType, CompatibleArrayType,
3807 enable_if_t <
3808 is_detected<iterator_t, CompatibleArrayType>::value&&
3809 is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
3810// special case for types like std::filesystem::path whose iterator's value_type are themselves
3811// c.f. https://github.com/nlohmann/json/pull/3073
3812 !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3813{
3814 static constexpr bool value =
3815 is_constructible<BasicJsonType,
3817};
3818
3819template<typename BasicJsonType, typename CompatibleArrayType>
3821 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3822
3823template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3824struct is_constructible_array_type_impl : std::false_type {};
3825
3826template<typename BasicJsonType, typename ConstructibleArrayType>
3828 BasicJsonType, ConstructibleArrayType,
3829 enable_if_t<std::is_same<ConstructibleArrayType,
3830 typename BasicJsonType::value_type>::value >>
3831 : std::true_type {};
3832
3833template<typename BasicJsonType, typename ConstructibleArrayType>
3835 BasicJsonType, ConstructibleArrayType,
3836 enable_if_t < !std::is_same<ConstructibleArrayType,
3837 typename BasicJsonType::value_type>::value&&
3838 !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3839 is_default_constructible<ConstructibleArrayType>::value&&
3840(std::is_move_assignable<ConstructibleArrayType>::value ||
3841 std::is_copy_assignable<ConstructibleArrayType>::value)&&
3842is_detected<iterator_t, ConstructibleArrayType>::value&&
3843is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3844is_detected<range_value_t, ConstructibleArrayType>::value&&
3845// special case for types like std::filesystem::path whose iterator's value_type are themselves
3846// c.f. https://github.com/nlohmann/json/pull/3073
3847!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3849 detected_t<range_value_t, ConstructibleArrayType >>::value >>
3850{
3852
3853 static constexpr bool value =
3854 std::is_same<value_type,
3855 typename BasicJsonType::array_t::value_type>::value ||
3856 has_from_json<BasicJsonType,
3859 BasicJsonType,
3861};
3862
3863template<typename BasicJsonType, typename ConstructibleArrayType>
3865 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3866
3867template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3868 typename = void>
3869struct is_compatible_integer_type_impl : std::false_type {};
3870
3871template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3873 RealIntegerType, CompatibleNumberIntegerType,
3874 enable_if_t < std::is_integral<RealIntegerType>::value&&
3875 std::is_integral<CompatibleNumberIntegerType>::value&&
3876 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3877{
3878 // is there an assert somewhere on overflows?
3879 using RealLimits = std::numeric_limits<RealIntegerType>;
3880 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3881
3882 static constexpr auto value =
3883 is_constructible<RealIntegerType,
3884 CompatibleNumberIntegerType>::value &&
3885 CompatibleLimits::is_integer &&
3886 RealLimits::is_signed == CompatibleLimits::is_signed;
3887};
3888
3889template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3891 : is_compatible_integer_type_impl<RealIntegerType,
3892 CompatibleNumberIntegerType> {};
3893
3894template<typename BasicJsonType, typename CompatibleType, typename = void>
3895struct is_compatible_type_impl: std::false_type {};
3896
3897template<typename BasicJsonType, typename CompatibleType>
3899 BasicJsonType, CompatibleType,
3900 enable_if_t<is_complete_type<CompatibleType>::value >>
3901{
3902 static constexpr bool value =
3904};
3905
3906template<typename BasicJsonType, typename CompatibleType>
3908 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3909
3910template<typename T1, typename T2>
3911struct is_constructible_tuple : std::false_type {};
3912
3913template<typename T1, typename... Args>
3914struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3915
3916// a naive helper to check if a type is an ordered_map (exploits the fact that
3917// ordered_map inherits capacity() from std::vector)
3918template <typename T>
3920{
3921 using one = char;
3922
3923 struct two
3924 {
3925 char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3926 };
3927
3928 template <typename C> static one test( decltype(&C::capacity) ) ;
3929 template <typename C> static two test(...);
3930
3931 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3932};
3933
3934// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3935template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3937{
3938 return static_cast<T>(value);
3939}
3940
3941template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3943{
3944 return value;
3945}
3946
3947} // namespace detail
3948} // namespace nlohmann
3949
3950// #include <nlohmann/detail/value_t.hpp>
3951
3952
3953#ifdef JSON_HAS_CPP_17
3954#include <experimental/filesystem>
3955#endif
3956
3957namespace nlohmann
3958{
3959namespace detail
3960{
3961template<typename BasicJsonType>
3962void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3963{
3964 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3965 {
3966 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
3967 }
3968 n = nullptr;
3969}
3970
3971// overloads for basic_json template parameters
3972template < typename BasicJsonType, typename ArithmeticType,
3973 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3974 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3975 int > = 0 >
3976void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3977{
3978 switch (static_cast<value_t>(j))
3979 {
3981 {
3982 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3983 break;
3984 }
3986 {
3987 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3988 break;
3989 }
3991 {
3992 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3993 break;
3994 }
3995
3996 case value_t::null:
3997 case value_t::object:
3998 case value_t::array:
3999 case value_t::string:
4000 case value_t::boolean:
4001 case value_t::binary:
4002 case value_t::discarded:
4003 default:
4004 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4005 }
4006}
4007
4008template<typename BasicJsonType>
4009void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4010{
4011 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4012 {
4013 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
4014 }
4015 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4016}
4017
4018template<typename BasicJsonType>
4019void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4020{
4021 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4022 {
4023 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
4024 }
4025 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4026}
4027
4028template <
4029 typename BasicJsonType, typename ConstructibleStringType,
4030 enable_if_t <
4032 !std::is_same<typename BasicJsonType::string_t,
4033 ConstructibleStringType>::value,
4034 int > = 0 >
4035void from_json(const BasicJsonType& j, ConstructibleStringType& s)
4036{
4037 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4038 {
4039 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
4040 }
4041
4042 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4043}
4044
4045template<typename BasicJsonType>
4046void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4047{
4048 get_arithmetic_value(j, val);
4049}
4050
4051template<typename BasicJsonType>
4052void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4053{
4054 get_arithmetic_value(j, val);
4055}
4056
4057template<typename BasicJsonType>
4058void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4059{
4060 get_arithmetic_value(j, val);
4061}
4062
4063template<typename BasicJsonType, typename EnumType,
4064 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4065void from_json(const BasicJsonType& j, EnumType& e)
4066{
4067 typename std::underlying_type<EnumType>::type val;
4068 get_arithmetic_value(j, val);
4069 e = static_cast<EnumType>(val);
4070}
4071
4072// forward_list doesn't have an insert method
4073template<typename BasicJsonType, typename T, typename Allocator,
4074 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4075void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4076{
4077 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4078 {
4079 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4080 }
4081 l.clear();
4082 std::transform(j.rbegin(), j.rend(),
4083 std::front_inserter(l), [](const BasicJsonType & i)
4084 {
4085 return i.template get<T>();
4086 });
4087}
4088
4089// valarray doesn't have an insert method
4090template<typename BasicJsonType, typename T,
4091 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4092void from_json(const BasicJsonType& j, std::valarray<T>& l)
4093{
4094 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4095 {
4096 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4097 }
4098 l.resize(j.size());
4099 std::transform(j.begin(), j.end(), std::begin(l),
4100 [](const BasicJsonType & elem)
4101 {
4102 return elem.template get<T>();
4103 });
4104}
4105
4106template<typename BasicJsonType, typename T, std::size_t N>
4107auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4108-> decltype(j.template get<T>(), void())
4109{
4110 for (std::size_t i = 0; i < N; ++i)
4111 {
4112 arr[i] = j.at(i).template get<T>();
4113 }
4114}
4115
4116template<typename BasicJsonType>
4117void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4118{
4119 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4120}
4121
4122template<typename BasicJsonType, typename T, std::size_t N>
4123auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4124 priority_tag<2> /*unused*/)
4125-> decltype(j.template get<T>(), void())
4126{
4127 for (std::size_t i = 0; i < N; ++i)
4128 {
4129 arr[i] = j.at(i).template get<T>();
4130 }
4131}
4132
4133template<typename BasicJsonType, typename ConstructibleArrayType,
4135 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4136 int> = 0>
4137auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4138-> decltype(
4139 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4140 j.template get<typename ConstructibleArrayType::value_type>(),
4141 void())
4142{
4143 using std::end;
4144
4145 ConstructibleArrayType ret;
4146 ret.reserve(j.size());
4147 std::transform(j.begin(), j.end(),
4148 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4149 {
4150 // get<BasicJsonType>() returns *this, this won't call a from_json
4151 // method when value_type is BasicJsonType
4152 return i.template get<typename ConstructibleArrayType::value_type>();
4153 });
4154 arr = std::move(ret);
4155}
4156
4157template<typename BasicJsonType, typename ConstructibleArrayType,
4159 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4160 int> = 0>
4161void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4162 priority_tag<0> /*unused*/)
4163{
4164 using std::end;
4165
4166 ConstructibleArrayType ret;
4167 std::transform(
4168 j.begin(), j.end(), std::inserter(ret, end(ret)),
4169 [](const BasicJsonType & i)
4170 {
4171 // get<BasicJsonType>() returns *this, this won't call a from_json
4172 // method when value_type is BasicJsonType
4173 return i.template get<typename ConstructibleArrayType::value_type>();
4174 });
4175 arr = std::move(ret);
4176}
4177
4178template < typename BasicJsonType, typename ConstructibleArrayType,
4179 enable_if_t <
4180 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4181 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4183 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4184 !is_basic_json<ConstructibleArrayType>::value,
4185 int > = 0 >
4186auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4187-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4188j.template get<typename ConstructibleArrayType::value_type>(),
4189void())
4190{
4191 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4192 {
4193 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4194 }
4195
4196 from_json_array_impl(j, arr, priority_tag<3> {});
4197}
4198
4199template < typename BasicJsonType, typename T, std::size_t... Idx >
4200std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4201 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4202{
4203 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4204}
4205
4206template < typename BasicJsonType, typename T, std::size_t N >
4207auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4208-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4209{
4210 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4211 {
4212 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4213 }
4214
4215 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4216}
4217
4218template<typename BasicJsonType>
4219void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4220{
4221 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4222 {
4223 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
4224 }
4225
4226 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4227}
4228
4229template<typename BasicJsonType, typename ConstructibleObjectType,
4230 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4231void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4232{
4233 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4234 {
4235 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
4236 }
4237
4238 ConstructibleObjectType ret;
4239 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4240 using value_type = typename ConstructibleObjectType::value_type;
4241 std::transform(
4242 inner_object->begin(), inner_object->end(),
4243 std::inserter(ret, ret.begin()),
4244 [](typename BasicJsonType::object_t::value_type const & p)
4245 {
4246 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4247 });
4248 obj = std::move(ret);
4249}
4250
4251// overload for arithmetic types, not chosen for basic_json template arguments
4252// (BooleanType, etc..); note: Is it really necessary to provide explicit
4253// overloads for boolean_t etc. in case of a custom BooleanType which is not
4254// an arithmetic type?
4255template < typename BasicJsonType, typename ArithmeticType,
4256 enable_if_t <
4257 std::is_arithmetic<ArithmeticType>::value&&
4258 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4259 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4260 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4261 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4262 int > = 0 >
4263void from_json(const BasicJsonType& j, ArithmeticType& val)
4264{
4265 switch (static_cast<value_t>(j))
4266 {
4268 {
4269 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4270 break;
4271 }
4273 {
4274 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4275 break;
4276 }
4278 {
4279 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4280 break;
4281 }
4282 case value_t::boolean:
4283 {
4284 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4285 break;
4286 }
4287
4288 case value_t::null:
4289 case value_t::object:
4290 case value_t::array:
4291 case value_t::string:
4292 case value_t::binary:
4293 case value_t::discarded:
4294 default:
4295 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4296 }
4297}
4298
4299template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4300std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4301{
4302 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4303}
4304
4305template < typename BasicJsonType, class A1, class A2 >
4306std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4307{
4308 return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4309 std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4310}
4311
4312template<typename BasicJsonType, typename A1, typename A2>
4313void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4314{
4315 p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4316}
4317
4318template<typename BasicJsonType, typename... Args>
4319std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4320{
4321 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4322}
4323
4324template<typename BasicJsonType, typename... Args>
4325void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4326{
4327 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4328}
4329
4330template<typename BasicJsonType, typename TupleRelated>
4331auto from_json(BasicJsonType&& j, TupleRelated&& t)
4332-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4333{
4334 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4335 {
4336 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4337 }
4338
4339 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4340}
4341
4342template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4343 typename = enable_if_t < !std::is_constructible <
4344 typename BasicJsonType::string_t, Key >::value >>
4345void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4346{
4347 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4348 {
4349 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4350 }
4351 m.clear();
4352 for (const auto& p : j)
4353 {
4354 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4355 {
4356 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4357 }
4358 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4359 }
4360}
4361
4362template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4363 typename = enable_if_t < !std::is_constructible <
4364 typename BasicJsonType::string_t, Key >::value >>
4365void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4366{
4367 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4368 {
4369 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4370 }
4371 m.clear();
4372 for (const auto& p : j)
4373 {
4374 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4375 {
4376 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4377 }
4378 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4379 }
4380}
4381
4382#ifdef JSON_HAS_CPP_17
4383template<typename BasicJsonType>
4384void from_json(const BasicJsonType& j, std::experimental::filesystem::path& p)
4385{
4386 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4387 {
4388 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
4389 }
4390 p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4391}
4392#endif
4393
4395{
4396 template<typename BasicJsonType, typename T>
4397 auto operator()(const BasicJsonType& j, T&& val) const
4398 noexcept(noexcept(from_json(j, std::forward<T>(val))))
4399 -> decltype(from_json(j, std::forward<T>(val)))
4400 {
4401 return from_json(j, std::forward<T>(val));
4402 }
4403};
4404} // namespace detail
4405
4409namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4410{
4411constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4412} // namespace
4413} // namespace nlohmann
4414
4415// #include <nlohmann/detail/conversions/to_json.hpp>
4416
4417
4418#include <algorithm> // copy
4419#include <iterator> // begin, end
4420#include <string> // string
4421#include <tuple> // tuple, get
4422#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4423#include <utility> // move, forward, declval, pair
4424#include <valarray> // valarray
4425#include <vector> // vector
4426
4427// #include <nlohmann/detail/macro_scope.hpp>
4428
4429// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4430
4431
4432#include <cstddef> // size_t
4433#include <iterator> // input_iterator_tag
4434#include <string> // string, to_string
4435#include <tuple> // tuple_size, get, tuple_element
4436#include <utility> // move
4437
4438// #include <nlohmann/detail/meta/type_traits.hpp>
4439
4440// #include <nlohmann/detail/value_t.hpp>
4441
4442
4443namespace nlohmann
4444{
4445namespace detail
4446{
4447template<typename string_type>
4448void int_to_string( string_type& target, std::size_t value )
4449{
4450 // For ADL
4451 using std::to_string;
4452 target = to_string(value);
4453}
4454template<typename IteratorType> class iteration_proxy_value
4455{
4456 public:
4457 using difference_type = std::ptrdiff_t;
4461 using iterator_category = std::input_iterator_tag;
4462 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4463
4464 private:
4466 IteratorType anchor;
4468 std::size_t array_index = 0;
4470 mutable std::size_t array_index_last = 0;
4475
4476 public:
4477 explicit iteration_proxy_value(IteratorType it) noexcept
4478 : anchor(std::move(it))
4479 {}
4480
4483 {
4484 return *this;
4485 }
4486
4489 {
4490 ++anchor;
4491 ++array_index;
4492
4493 return *this;
4494 }
4495
4498 {
4499 return anchor == o.anchor;
4500 }
4501
4504 {
4505 return anchor != o.anchor;
4506 }
4507
4509 const string_type& key() const
4510 {
4511 JSON_ASSERT(anchor.m_object != nullptr);
4512
4513 switch (anchor.m_object->type())
4514 {
4515 // use integer array index as key
4516 case value_t::array:
4517 {
4519 {
4522 }
4523 return array_index_str;
4524 }
4525
4526 // use key from the object
4527 case value_t::object:
4528 return anchor.key();
4529
4530 // use an empty key for all primitive types
4531 case value_t::null:
4532 case value_t::string:
4533 case value_t::boolean:
4537 case value_t::binary:
4538 case value_t::discarded:
4539 default:
4540 return empty_str;
4541 }
4542 }
4543
4545 typename IteratorType::reference value() const
4546 {
4547 return anchor.value();
4548 }
4549};
4550
4552template<typename IteratorType> class iteration_proxy
4553{
4554 private:
4556 typename IteratorType::reference container;
4557
4558 public:
4560 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4561 : container(cont) {}
4562
4565 {
4567 }
4568
4571 {
4573 }
4574};
4575// Structured Bindings Support
4576// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4577// And see https://github.com/nlohmann/json/pull/1391
4578template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4580{
4581 return i.key();
4582}
4583// Structured Bindings Support
4584// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4585// And see https://github.com/nlohmann/json/pull/1391
4586template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4587auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4588{
4589 return i.value();
4590}
4591} // namespace detail
4592} // namespace nlohmann
4593
4594// The Addition to the STD Namespace is required to add
4595// Structured Bindings Support to the iteration_proxy_value class
4596// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4597// And see https://github.com/nlohmann/json/pull/1391
4598namespace std
4599{
4600#if defined(__clang__)
4601 // Fix: https://github.com/nlohmann/json/issues/1401
4602 #pragma clang diagnostic push
4603 #pragma clang diagnostic ignored "-Wmismatched-tags"
4604#endif
4605template<typename IteratorType>
4606class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4607 : public std::integral_constant<std::size_t, 2> {};
4608
4609template<std::size_t N, typename IteratorType>
4610class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4611{
4612 public:
4613 using type = decltype(
4614 get<N>(std::declval <
4616};
4617#if defined(__clang__)
4618 #pragma clang diagnostic pop
4619#endif
4620} // namespace std
4621
4622// #include <nlohmann/detail/meta/cpp_future.hpp>
4623
4624// #include <nlohmann/detail/meta/type_traits.hpp>
4625
4626// #include <nlohmann/detail/value_t.hpp>
4627
4628
4629#ifdef JSON_HAS_CPP_17
4630 #include <experimental/filesystem>
4631#endif
4632
4633namespace nlohmann
4634{
4635namespace detail
4636{
4638// constructors //
4640
4641/*
4642 * Note all external_constructor<>::construct functions need to call
4643 * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
4644 * allocated value (e.g., a string). See bug issue
4645 * https://github.com/nlohmann/json/issues/2865 for more information.
4646 */
4647
4648template<value_t> struct external_constructor;
4649
4650template<>
4652{
4653 template<typename BasicJsonType>
4654 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4655 {
4656 j.m_value.destroy(j.m_type);
4657 j.m_type = value_t::boolean;
4658 j.m_value = b;
4659 j.assert_invariant();
4660 }
4661};
4662
4663template<>
4665{
4666 template<typename BasicJsonType>
4667 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4668 {
4669 j.m_value.destroy(j.m_type);
4670 j.m_type = value_t::string;
4671 j.m_value = s;
4672 j.assert_invariant();
4673 }
4674
4675 template<typename BasicJsonType>
4676 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4677 {
4678 j.m_value.destroy(j.m_type);
4679 j.m_type = value_t::string;
4680 j.m_value = std::move(s);
4681 j.assert_invariant();
4682 }
4683
4684 template < typename BasicJsonType, typename CompatibleStringType,
4685 enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4686 int > = 0 >
4687 static void construct(BasicJsonType& j, const CompatibleStringType& str)
4688 {
4689 j.m_value.destroy(j.m_type);
4690 j.m_type = value_t::string;
4691 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4692 j.assert_invariant();
4693 }
4694};
4695
4696template<>
4698{
4699 template<typename BasicJsonType>
4700 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4701 {
4702 j.m_value.destroy(j.m_type);
4703 j.m_type = value_t::binary;
4704 j.m_value = typename BasicJsonType::binary_t(b);
4705 j.assert_invariant();
4706 }
4707
4708 template<typename BasicJsonType>
4709 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4710 {
4711 j.m_value.destroy(j.m_type);
4712 j.m_type = value_t::binary;
4713 j.m_value = typename BasicJsonType::binary_t(std::move(b));
4714 j.assert_invariant();
4715 }
4716};
4717
4718template<>
4720{
4721 template<typename BasicJsonType>
4722 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4723 {
4724 j.m_value.destroy(j.m_type);
4725 j.m_type = value_t::number_float;
4726 j.m_value = val;
4727 j.assert_invariant();
4728 }
4729};
4730
4731template<>
4733{
4734 template<typename BasicJsonType>
4735 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4736 {
4737 j.m_value.destroy(j.m_type);
4738 j.m_type = value_t::number_unsigned;
4739 j.m_value = val;
4740 j.assert_invariant();
4741 }
4742};
4743
4744template<>
4746{
4747 template<typename BasicJsonType>
4748 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4749 {
4750 j.m_value.destroy(j.m_type);
4751 j.m_type = value_t::number_integer;
4752 j.m_value = val;
4753 j.assert_invariant();
4754 }
4755};
4756
4757template<>
4759{
4760 template<typename BasicJsonType>
4761 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4762 {
4763 j.m_value.destroy(j.m_type);
4764 j.m_type = value_t::array;
4765 j.m_value = arr;
4766 j.set_parents();
4767 j.assert_invariant();
4768 }
4769
4770 template<typename BasicJsonType>
4771 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4772 {
4773 j.m_value.destroy(j.m_type);
4774 j.m_type = value_t::array;
4775 j.m_value = std::move(arr);
4776 j.set_parents();
4777 j.assert_invariant();
4778 }
4779
4780 template < typename BasicJsonType, typename CompatibleArrayType,
4781 enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4782 int > = 0 >
4783 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4784 {
4785 using std::begin;
4786 using std::end;
4787
4788 j.m_value.destroy(j.m_type);
4789 j.m_type = value_t::array;
4790 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4791 j.set_parents();
4792 j.assert_invariant();
4793 }
4794
4795 template<typename BasicJsonType>
4796 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4797 {
4798 j.m_value.destroy(j.m_type);
4799 j.m_type = value_t::array;
4800 j.m_value = value_t::array;
4801 j.m_value.array->reserve(arr.size());
4802 for (const bool x : arr)
4803 {
4804 j.m_value.array->push_back(x);
4805 j.set_parent(j.m_value.array->back());
4806 }
4807 j.assert_invariant();
4808 }
4809
4810 template<typename BasicJsonType, typename T,
4812 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4813 {
4814 j.m_value.destroy(j.m_type);
4815 j.m_type = value_t::array;
4816 j.m_value = value_t::array;
4817 j.m_value.array->resize(arr.size());
4818 if (arr.size() > 0)
4819 {
4820 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4821 }
4822 j.set_parents();
4823 j.assert_invariant();
4824 }
4825};
4826
4827template<>
4829{
4830 template<typename BasicJsonType>
4831 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4832 {
4833 j.m_value.destroy(j.m_type);
4834 j.m_type = value_t::object;
4835 j.m_value = obj;
4836 j.set_parents();
4837 j.assert_invariant();
4838 }
4839
4840 template<typename BasicJsonType>
4841 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4842 {
4843 j.m_value.destroy(j.m_type);
4844 j.m_type = value_t::object;
4845 j.m_value = std::move(obj);
4846 j.set_parents();
4847 j.assert_invariant();
4848 }
4849
4850 template < typename BasicJsonType, typename CompatibleObjectType,
4851 enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
4852 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4853 {
4854 using std::begin;
4855 using std::end;
4856
4857 j.m_value.destroy(j.m_type);
4858 j.m_type = value_t::object;
4859 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4860 j.set_parents();
4861 j.assert_invariant();
4862 }
4863};
4864
4866// to_json //
4868
4869template<typename BasicJsonType, typename T,
4870 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4871void to_json(BasicJsonType& j, T b) noexcept
4872{
4874}
4875
4876template<typename BasicJsonType, typename CompatibleString,
4877 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4878void to_json(BasicJsonType& j, const CompatibleString& s)
4879{
4881}
4882
4883template<typename BasicJsonType>
4884void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4885{
4887}
4888
4889template<typename BasicJsonType, typename FloatType,
4890 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4891void to_json(BasicJsonType& j, FloatType val) noexcept
4892{
4893 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4894}
4895
4896template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4897 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4898void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4899{
4900 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4901}
4902
4903template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4904 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4905void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4906{
4907 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4908}
4909
4910template<typename BasicJsonType, typename EnumType,
4911 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4912void to_json(BasicJsonType& j, EnumType e) noexcept
4913{
4914 using underlying_type = typename std::underlying_type<EnumType>::type;
4915 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4916}
4917
4918template<typename BasicJsonType>
4919void to_json(BasicJsonType& j, const std::vector<bool>& e)
4920{
4922}
4923
4924template < typename BasicJsonType, typename CompatibleArrayType,
4925 enable_if_t < is_compatible_array_type<BasicJsonType,
4926 CompatibleArrayType>::value&&
4927 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4929 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4930 !is_basic_json<CompatibleArrayType>::value,
4931 int > = 0 >
4932void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4933{
4935}
4936
4937template<typename BasicJsonType>
4938void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4939{
4941}
4942
4943template<typename BasicJsonType, typename T,
4944 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4945void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4946{
4948}
4949
4950template<typename BasicJsonType>
4951void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4952{
4954}
4955
4956template < typename BasicJsonType, typename CompatibleObjectType,
4957 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4958void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4959{
4961}
4962
4963template<typename BasicJsonType>
4964void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4965{
4967}
4968
4969template <
4970 typename BasicJsonType, typename T, std::size_t N,
4971 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4972 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4973 int > = 0 >
4974void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4975{
4977}
4978
4979template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4980void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4981{
4982 j = { p.first, p.second };
4983}
4984
4985// for https://github.com/nlohmann/json/pull/1134
4986template<typename BasicJsonType, typename T,
4987 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4988void to_json(BasicJsonType& j, const T& b)
4989{
4990 j = { {b.key(), b.value()} };
4991}
4992
4993template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4994void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4995{
4996 j = { std::get<Idx>(t)... };
4997}
4998
4999template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
5000void to_json(BasicJsonType& j, const T& t)
5001{
5002 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
5003}
5004
5005#ifdef JSON_HAS_CPP_17
5006template<typename BasicJsonType>
5007void to_json(BasicJsonType& j, const std::experimental::filesystem::path& p)
5008{
5009 j = p.string();
5010}
5011#endif
5012
5014{
5015 template<typename BasicJsonType, typename T>
5016 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5017 -> decltype(to_json(j, std::forward<T>(val)), void())
5018 {
5019 return to_json(j, std::forward<T>(val));
5020 }
5021};
5022} // namespace detail
5023
5027namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5028{
5029constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
5030} // namespace
5031} // namespace nlohmann
5032
5033// #include <nlohmann/detail/meta/identity_tag.hpp>
5034
5035// #include <nlohmann/detail/meta/type_traits.hpp>
5036
5037
5038namespace nlohmann
5039{
5040
5041template<typename ValueType, typename>
5043{
5055 template<typename BasicJsonType, typename TargetType = ValueType>
5056 static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
5057 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5058 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5059 {
5060 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5061 }
5062
5075 template<typename BasicJsonType, typename TargetType = ValueType>
5076 static auto from_json(BasicJsonType && j) noexcept(
5077 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5078 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5079 {
5080 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5081 }
5082
5092 template<typename BasicJsonType, typename TargetType = ValueType>
5093 static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5094 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5095 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5096 {
5097 ::nlohmann::to_json(j, std::forward<TargetType>(val));
5098 }
5099};
5100} // namespace nlohmann
5101
5102// #include <nlohmann/byte_container_with_subtype.hpp>
5103
5104
5105#include <cstdint> // uint8_t, uint64_t
5106#include <tuple> // tie
5107#include <utility> // move
5108
5109namespace nlohmann
5110{
5111
5125template<typename BinaryType>
5126class byte_container_with_subtype : public BinaryType
5127{
5128 public:
5130 using container_type = BinaryType;
5132 using subtype_type = std::uint64_t;
5133
5135 : container_type()
5136 {}
5137
5139 : container_type(b)
5140 {}
5141
5142 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5143 : container_type(std::move(b))
5144 {}
5145
5147 : container_type(b)
5148 , m_subtype(subtype_)
5149 , m_has_subtype(true)
5150 {}
5151
5152 byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5153 : container_type(std::move(b))
5154 , m_subtype(subtype_)
5155 , m_has_subtype(true)
5156 {}
5157
5159 {
5160 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5161 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5162 }
5163
5165 {
5166 return !(rhs == *this);
5167 }
5168
5187 void set_subtype(subtype_type subtype_) noexcept
5188 {
5189 m_subtype = subtype_;
5190 m_has_subtype = true;
5191 }
5192
5215 constexpr subtype_type subtype() const noexcept
5216 {
5217 return m_has_subtype ? m_subtype : subtype_type(-1);
5218 }
5219
5236 constexpr bool has_subtype() const noexcept
5237 {
5238 return m_has_subtype;
5239 }
5240
5260 void clear_subtype() noexcept
5261 {
5262 m_subtype = 0;
5263 m_has_subtype = false;
5264 }
5265
5266 private:
5268 bool m_has_subtype = false;
5269};
5270
5271} // namespace nlohmann
5272
5273// #include <nlohmann/detail/conversions/from_json.hpp>
5274
5275// #include <nlohmann/detail/conversions/to_json.hpp>
5276
5277// #include <nlohmann/detail/exceptions.hpp>
5278
5279// #include <nlohmann/detail/hash.hpp>
5280
5281
5282#include <cstdint> // uint8_t
5283#include <cstddef> // size_t
5284#include <functional> // hash
5285
5286// #include <nlohmann/detail/macro_scope.hpp>
5287
5288// #include <nlohmann/detail/value_t.hpp>
5289
5290
5291namespace nlohmann
5292{
5293namespace detail
5294{
5295
5296// boost::hash_combine
5297inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5298{
5299 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5300 return seed;
5301}
5302
5314template<typename BasicJsonType>
5315std::size_t hash(const BasicJsonType& j)
5316{
5317 using string_t = typename BasicJsonType::string_t;
5318 using number_integer_t = typename BasicJsonType::number_integer_t;
5319 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5320 using number_float_t = typename BasicJsonType::number_float_t;
5321
5322 const auto type = static_cast<std::size_t>(j.type());
5323 switch (j.type())
5324 {
5325 case BasicJsonType::value_t::null:
5326 case BasicJsonType::value_t::discarded:
5327 {
5328 return combine(type, 0);
5329 }
5330
5331 case BasicJsonType::value_t::object:
5332 {
5333 auto seed = combine(type, j.size());
5334 for (const auto& element : j.items())
5335 {
5336 const auto h = std::hash<string_t> {}(element.key());
5337 seed = combine(seed, h);
5338 seed = combine(seed, hash(element.value()));
5339 }
5340 return seed;
5341 }
5342
5343 case BasicJsonType::value_t::array:
5344 {
5345 auto seed = combine(type, j.size());
5346 for (const auto& element : j)
5347 {
5348 seed = combine(seed, hash(element));
5349 }
5350 return seed;
5351 }
5352
5353 case BasicJsonType::value_t::string:
5354 {
5355 const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5356 return combine(type, h);
5357 }
5358
5359 case BasicJsonType::value_t::boolean:
5360 {
5361 const auto h = std::hash<bool> {}(j.template get<bool>());
5362 return combine(type, h);
5363 }
5364
5365 case BasicJsonType::value_t::number_integer:
5366 {
5367 const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5368 return combine(type, h);
5369 }
5370
5371 case BasicJsonType::value_t::number_unsigned:
5372 {
5373 const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5374 return combine(type, h);
5375 }
5376
5377 case BasicJsonType::value_t::number_float:
5378 {
5379 const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5380 return combine(type, h);
5381 }
5382
5383 case BasicJsonType::value_t::binary:
5384 {
5385 auto seed = combine(type, j.get_binary().size());
5386 const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5387 seed = combine(seed, h);
5388 seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5389 for (const auto byte : j.get_binary())
5390 {
5391 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5392 }
5393 return seed;
5394 }
5395
5396 default: // LCOV_EXCL_LINE
5397 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5398 return 0; // LCOV_EXCL_LINE
5399 }
5400}
5401
5402} // namespace detail
5403} // namespace nlohmann
5404
5405// #include <nlohmann/detail/input/binary_reader.hpp>
5406
5407
5408#include <algorithm> // generate_n
5409#include <array> // array
5410#include <cmath> // ldexp
5411#include <cstddef> // size_t
5412#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5413#include <cstdio> // snprintf
5414#include <cstring> // memcpy
5415#include <iterator> // back_inserter
5416#include <limits> // numeric_limits
5417#include <string> // char_traits, string
5418#include <utility> // make_pair, move
5419#include <vector> // vector
5420
5421// #include <nlohmann/detail/exceptions.hpp>
5422
5423// #include <nlohmann/detail/input/input_adapters.hpp>
5424
5425
5426#include <array> // array
5427#include <cstddef> // size_t
5428#include <cstring> // strlen
5429#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5430#include <memory> // shared_ptr, make_shared, addressof
5431#include <numeric> // accumulate
5432#include <string> // string, char_traits
5433#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5434#include <utility> // pair, declval
5435
5436#ifndef JSON_NO_IO
5437 #include <cstdio> // FILE *
5438 #include <istream> // istream
5439#endif // JSON_NO_IO
5440
5441// #include <nlohmann/detail/iterators/iterator_traits.hpp>
5442
5443// #include <nlohmann/detail/macro_scope.hpp>
5444
5445
5446namespace nlohmann
5447{
5448namespace detail
5449{
5452
5454// input adapters //
5456
5457#ifndef JSON_NO_IO
5463{
5464 public:
5465 using char_type = char;
5466
5468 explicit file_input_adapter(std::FILE* f) noexcept
5469 : m_file(f)
5470 {}
5471
5472 // make class move-only
5475 file_input_adapter& operator=(const file_input_adapter&) = delete;
5478
5479 std::char_traits<char>::int_type get_character() noexcept
5480 {
5481 return std::fgetc(m_file);
5482 }
5483
5484 private:
5486 std::FILE* m_file;
5487};
5488
5489
5500{
5501 public:
5502 using char_type = char;
5503
5505 {
5506 // clear stream flags; we use underlying streambuf I/O, do not
5507 // maintain ifstream flags, except eof
5508 if (is != nullptr)
5509 {
5510 is->clear(is->rdstate() & std::ios::eofbit);
5511 }
5512 }
5513
5514 explicit input_stream_adapter(std::istream& i)
5515 : is(&i), sb(i.rdbuf())
5516 {}
5517
5518 // delete because of pointer members
5522
5524 : is(rhs.is), sb(rhs.sb)
5525 {
5526 rhs.is = nullptr;
5527 rhs.sb = nullptr;
5528 }
5529
5530 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5531 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5532 // end up as the same value, eg. 0xFFFFFFFF.
5533 std::char_traits<char>::int_type get_character()
5534 {
5535 auto res = sb->sbumpc();
5536 // set eof manually, as we don't use the istream interface.
5537 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5538 {
5539 is->clear(is->rdstate() | std::ios::eofbit);
5540 }
5541 return res;
5542 }
5543
5544 private:
5546 std::istream* is = nullptr;
5547 std::streambuf* sb = nullptr;
5548};
5549#endif // JSON_NO_IO
5550
5551// General-purpose iterator-based adapter. It might not be as fast as
5552// theoretically possible for some containers, but it is extremely versatile.
5553template<typename IteratorType>
5555{
5556 public:
5557 using char_type = typename std::iterator_traits<IteratorType>::value_type;
5558
5559 iterator_input_adapter(IteratorType first, IteratorType last)
5560 : current(std::move(first)), end(std::move(last))
5561 {}
5562
5563 typename std::char_traits<char_type>::int_type get_character()
5564 {
5566 {
5567 auto result = std::char_traits<char_type>::to_int_type(*current);
5568 std::advance(current, 1);
5569 return result;
5570 }
5571
5572 return std::char_traits<char_type>::eof();
5573 }
5574
5575 private:
5576 IteratorType current;
5577 IteratorType end;
5578
5579 template<typename BaseInputAdapter, size_t T>
5581
5582 bool empty() const
5583 {
5584 return current == end;
5585 }
5586};
5587
5588
5589template<typename BaseInputAdapter, size_t T>
5591
5592template<typename BaseInputAdapter>
5593struct wide_string_input_helper<BaseInputAdapter, 4>
5594{
5595 // UTF-32
5596 static void fill_buffer(BaseInputAdapter& input,
5597 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5598 size_t& utf8_bytes_index,
5599 size_t& utf8_bytes_filled)
5600 {
5601 utf8_bytes_index = 0;
5602
5603 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5604 {
5605 utf8_bytes[0] = std::char_traits<char>::eof();
5606 utf8_bytes_filled = 1;
5607 }
5608 else
5609 {
5610 // get the current character
5611 const auto wc = input.get_character();
5612
5613 // UTF-32 to UTF-8 encoding
5614 if (wc < 0x80)
5615 {
5616 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5617 utf8_bytes_filled = 1;
5618 }
5619 else if (wc <= 0x7FF)
5620 {
5621 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5622 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5623 utf8_bytes_filled = 2;
5624 }
5625 else if (wc <= 0xFFFF)
5626 {
5627 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5628 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5629 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5630 utf8_bytes_filled = 3;
5631 }
5632 else if (wc <= 0x10FFFF)
5633 {
5634 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5635 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5636 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5637 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5638 utf8_bytes_filled = 4;
5639 }
5640 else
5641 {
5642 // unknown character
5643 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5644 utf8_bytes_filled = 1;
5645 }
5646 }
5647 }
5648};
5649
5650template<typename BaseInputAdapter>
5651struct wide_string_input_helper<BaseInputAdapter, 2>
5652{
5653 // UTF-16
5654 static void fill_buffer(BaseInputAdapter& input,
5655 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5656 size_t& utf8_bytes_index,
5657 size_t& utf8_bytes_filled)
5658 {
5659 utf8_bytes_index = 0;
5660
5661 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5662 {
5663 utf8_bytes[0] = std::char_traits<char>::eof();
5664 utf8_bytes_filled = 1;
5665 }
5666 else
5667 {
5668 // get the current character
5669 const auto wc = input.get_character();
5670
5671 // UTF-16 to UTF-8 encoding
5672 if (wc < 0x80)
5673 {
5674 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5675 utf8_bytes_filled = 1;
5676 }
5677 else if (wc <= 0x7FF)
5678 {
5679 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5680 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5681 utf8_bytes_filled = 2;
5682 }
5683 else if (0xD800 > wc || wc >= 0xE000)
5684 {
5685 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5686 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5687 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5688 utf8_bytes_filled = 3;
5689 }
5690 else
5691 {
5692 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5693 {
5694 const auto wc2 = static_cast<unsigned int>(input.get_character());
5695 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5696 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5697 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5698 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5699 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5700 utf8_bytes_filled = 4;
5701 }
5702 else
5703 {
5704 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5705 utf8_bytes_filled = 1;
5706 }
5707 }
5708 }
5709 }
5710};
5711
5712// Wraps another input apdater to convert wide character types into individual bytes.
5713template<typename BaseInputAdapter, typename WideCharType>
5715{
5716 public:
5717 using char_type = char;
5718
5719 wide_string_input_adapter(BaseInputAdapter base)
5720 : base_adapter(base) {}
5721
5722 typename std::char_traits<char>::int_type get_character() noexcept
5723 {
5724 // check if buffer needs to be filled
5726 {
5727 fill_buffer<sizeof(WideCharType)>();
5728
5731 }
5732
5733 // use buffer
5736 return utf8_bytes[utf8_bytes_index++];
5737 }
5738
5739 private:
5740 BaseInputAdapter base_adapter;
5741
5742 template<size_t T>
5744 {
5746 }
5747
5749 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5750
5752 std::size_t utf8_bytes_index = 0;
5754 std::size_t utf8_bytes_filled = 0;
5755};
5756
5757
5758template<typename IteratorType, typename Enable = void>
5760{
5761 using iterator_type = IteratorType;
5762 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5764
5765 static adapter_type create(IteratorType first, IteratorType last)
5766 {
5767 return adapter_type(std::move(first), std::move(last));
5768 }
5769};
5770
5771template<typename T>
5773{
5774 using value_type = typename std::iterator_traits<T>::value_type;
5775 enum
5776 {
5777 value = sizeof(value_type) > 1
5778 };
5779};
5780
5781template<typename IteratorType>
5783{
5784 using iterator_type = IteratorType;
5785 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5788
5789 static adapter_type create(IteratorType first, IteratorType last)
5790 {
5791 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5792 }
5793};
5794
5795// General purpose iterator-based input
5796template<typename IteratorType>
5798{
5800 return factory_type::create(first, last);
5801}
5802
5803// Convenience shorthand from container to iterator
5804// Enables ADL on begin(container) and end(container)
5805// Encloses the using declarations in namespace for not to leak them to outside scope
5806
5807namespace container_input_adapter_factory_impl
5808{
5809
5810using std::begin;
5811using std::end;
5812
5813template<typename ContainerType, typename Enable = void>
5815
5816template<typename ContainerType>
5818 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
5819 {
5820 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
5821
5822 static adapter_type create(const ContainerType& container)
5823{
5824 return input_adapter(begin(container), end(container));
5825}
5826 };
5827
5828} // namespace container_input_adapter_factory_impl
5829
5830template<typename ContainerType>
5832{
5834}
5835
5836#ifndef JSON_NO_IO
5837// Special cases with fast paths
5838inline file_input_adapter input_adapter(std::FILE* file)
5839{
5840 return file_input_adapter(file);
5841}
5842
5843inline input_stream_adapter input_adapter(std::istream& stream)
5844{
5845 return input_stream_adapter(stream);
5846}
5847
5848inline input_stream_adapter input_adapter(std::istream&& stream)
5849{
5850 return input_stream_adapter(stream);
5851}
5852#endif // JSON_NO_IO
5853
5854using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5855
5856// Null-delimited strings, and the like.
5857template < typename CharT,
5858 typename std::enable_if <
5859 std::is_pointer<CharT>::value&&
5860 !std::is_array<CharT>::value&&
5861 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5862 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5863 int >::type = 0 >
5865{
5866 auto length = std::strlen(reinterpret_cast<const char*>(b));
5867 const auto* ptr = reinterpret_cast<const char*>(b);
5868 return input_adapter(ptr, ptr + length);
5869}
5870
5871template<typename T, std::size_t N>
5872auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5873{
5874 return input_adapter(array, array + N);
5875}
5876
5877// This class only handles inputs of input_buffer_adapter type.
5878// It's required so that expressions like {ptr, len} can be implicitly casted
5879// to the correct adapter.
5881{
5882 public:
5883 template < typename CharT,
5884 typename std::enable_if <
5885 std::is_pointer<CharT>::value&&
5886 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5887 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5888 int >::type = 0 >
5889 span_input_adapter(CharT b, std::size_t l)
5890 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5891
5892 template<class IteratorType,
5893 typename std::enable_if<
5894 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5895 int>::type = 0>
5896 span_input_adapter(IteratorType first, IteratorType last)
5897 : ia(input_adapter(first, last)) {}
5898
5900 {
5901 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5902 }
5903
5904 private:
5906};
5907} // namespace detail
5908} // namespace nlohmann
5909
5910// #include <nlohmann/detail/input/json_sax.hpp>
5911
5912
5913#include <cstddef>
5914#include <string> // string
5915#include <utility> // move
5916#include <vector> // vector
5917
5918// #include <nlohmann/detail/exceptions.hpp>
5919
5920// #include <nlohmann/detail/macro_scope.hpp>
5921
5922
5923namespace nlohmann
5924{
5925
5934template<typename BasicJsonType>
5936{
5937 using number_integer_t = typename BasicJsonType::number_integer_t;
5938 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5939 using number_float_t = typename BasicJsonType::number_float_t;
5940 using string_t = typename BasicJsonType::string_t;
5941 using binary_t = typename BasicJsonType::binary_t;
5942
5947 virtual bool null() = 0;
5948
5954 virtual bool boolean(bool val) = 0;
5955
5961 virtual bool number_integer(number_integer_t val) = 0;
5962
5968 virtual bool number_unsigned(number_unsigned_t val) = 0;
5969
5976 virtual bool number_float(number_float_t val, const string_t& s) = 0;
5977
5984 virtual bool string(string_t& val) = 0;
5985
5992 virtual bool binary(binary_t& val) = 0;
5993
6000 virtual bool start_object(std::size_t elements) = 0;
6001
6008 virtual bool key(string_t& val) = 0;
6009
6014 virtual bool end_object() = 0;
6015
6022 virtual bool start_array(std::size_t elements) = 0;
6023
6028 virtual bool end_array() = 0;
6029
6037 virtual bool parse_error(std::size_t position,
6038 const std::string& last_token,
6039 const detail::exception& ex) = 0;
6040
6041 json_sax() = default;
6042 json_sax(const json_sax&) = default;
6043 json_sax(json_sax&&) noexcept = default;
6044 json_sax& operator=(const json_sax&) = default;
6045 json_sax& operator=(json_sax&&) noexcept = default;
6046 virtual ~json_sax() = default;
6047};
6048
6049
6050namespace detail
6051{
6065template<typename BasicJsonType>
6067{
6068 public:
6069 using number_integer_t = typename BasicJsonType::number_integer_t;
6070 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6071 using number_float_t = typename BasicJsonType::number_float_t;
6072 using string_t = typename BasicJsonType::string_t;
6073 using binary_t = typename BasicJsonType::binary_t;
6074
6080 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6081 : root(r), allow_exceptions(allow_exceptions_)
6082 {}
6083
6084 // make class move-only
6086 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6088 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6090
6091 bool null()
6092 {
6093 handle_value(nullptr);
6094 return true;
6095 }
6096
6097 bool boolean(bool val)
6098 {
6099 handle_value(val);
6100 return true;
6101 }
6102
6104 {
6105 handle_value(val);
6106 return true;
6107 }
6108
6110 {
6111 handle_value(val);
6112 return true;
6113 }
6114
6115 bool number_float(number_float_t val, const string_t& /*unused*/)
6116 {
6117 handle_value(val);
6118 return true;
6119 }
6120
6121 bool string(string_t& val)
6122 {
6123 handle_value(val);
6124 return true;
6125 }
6126
6127 bool binary(binary_t& val)
6128 {
6129 handle_value(std::move(val));
6130 return true;
6131 }
6132
6133 bool start_object(std::size_t len)
6134 {
6135 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6136
6137 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6138 {
6139 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6140 }
6141
6142 return true;
6143 }
6144
6145 bool key(string_t& val)
6146 {
6147 // add null at given key and store the reference for later
6148 object_element = &(ref_stack.back()->m_value.object->operator[](val));
6149 return true;
6150 }
6151
6153 {
6154 ref_stack.back()->set_parents();
6155 ref_stack.pop_back();
6156 return true;
6157 }
6158
6159 bool start_array(std::size_t len)
6160 {
6161 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6162
6163 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6164 {
6165 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6166 }
6167
6168 return true;
6169 }
6170
6172 {
6173 ref_stack.back()->set_parents();
6174 ref_stack.pop_back();
6175 return true;
6176 }
6177
6178 template<class Exception>
6179 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6180 const Exception& ex)
6181 {
6182 errored = true;
6183 static_cast<void>(ex);
6184 if (allow_exceptions)
6185 {
6186 JSON_THROW(ex);
6187 }
6188 return false;
6189 }
6190
6191 constexpr bool is_errored() const
6192 {
6193 return errored;
6194 }
6195
6196 private:
6203 template<typename Value>
6205 BasicJsonType* handle_value(Value&& v)
6206 {
6207 if (ref_stack.empty())
6208 {
6209 root = BasicJsonType(std::forward<Value>(v));
6210 return &root;
6211 }
6212
6213 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6214
6215 if (ref_stack.back()->is_array())
6216 {
6217 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6218 return &(ref_stack.back()->m_value.array->back());
6219 }
6220
6221 JSON_ASSERT(ref_stack.back()->is_object());
6222 JSON_ASSERT(object_element);
6223 *object_element = BasicJsonType(std::forward<Value>(v));
6224 return object_element;
6225 }
6226
6228 BasicJsonType& root;
6230 std::vector<BasicJsonType*> ref_stack {};
6232 BasicJsonType* object_element = nullptr;
6234 bool errored = false;
6236 const bool allow_exceptions = true;
6237};
6238
6239template<typename BasicJsonType>
6241{
6242 public:
6243 using number_integer_t = typename BasicJsonType::number_integer_t;
6244 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6245 using number_float_t = typename BasicJsonType::number_float_t;
6246 using string_t = typename BasicJsonType::string_t;
6247 using binary_t = typename BasicJsonType::binary_t;
6248 using parser_callback_t = typename BasicJsonType::parser_callback_t;
6249 using parse_event_t = typename BasicJsonType::parse_event_t;
6250
6252 const parser_callback_t cb,
6253 const bool allow_exceptions_ = true)
6254 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6255 {
6256 keep_stack.push_back(true);
6257 }
6258
6259 // make class move-only
6261 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6263 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6265
6266 bool null()
6267 {
6268 handle_value(nullptr);
6269 return true;
6270 }
6271
6272 bool boolean(bool val)
6273 {
6274 handle_value(val);
6275 return true;
6276 }
6277
6279 {
6280 handle_value(val);
6281 return true;
6282 }
6283
6285 {
6286 handle_value(val);
6287 return true;
6288 }
6289
6290 bool number_float(number_float_t val, const string_t& /*unused*/)
6291 {
6292 handle_value(val);
6293 return true;
6294 }
6295
6296 bool string(string_t& val)
6297 {
6298 handle_value(val);
6299 return true;
6300 }
6301
6302 bool binary(binary_t& val)
6303 {
6304 handle_value(std::move(val));
6305 return true;
6306 }
6307
6308 bool start_object(std::size_t len)
6309 {
6310 // check callback for object start
6311 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6312 keep_stack.push_back(keep);
6313
6314 auto val = handle_value(BasicJsonType::value_t::object, true);
6315 ref_stack.push_back(val.second);
6316
6317 // check object limit
6318 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6319 {
6320 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6321 }
6322
6323 return true;
6324 }
6325
6326 bool key(string_t& val)
6327 {
6328 BasicJsonType k = BasicJsonType(val);
6329
6330 // check callback for key
6331 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6332 key_keep_stack.push_back(keep);
6333
6334 // add discarded value at given key and store the reference for later
6335 if (keep && ref_stack.back())
6336 {
6337 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6338 }
6339
6340 return true;
6341 }
6342
6344 {
6345 if (ref_stack.back())
6346 {
6347 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6348 {
6349 // discard object
6350 *ref_stack.back() = discarded;
6351 }
6352 else
6353 {
6354 ref_stack.back()->set_parents();
6355 }
6356 }
6357
6358 JSON_ASSERT(!ref_stack.empty());
6359 JSON_ASSERT(!keep_stack.empty());
6360 ref_stack.pop_back();
6361 keep_stack.pop_back();
6362
6363 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6364 {
6365 // remove discarded value
6366 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6367 {
6368 if (it->is_discarded())
6369 {
6370 ref_stack.back()->erase(it);
6371 break;
6372 }
6373 }
6374 }
6375
6376 return true;
6377 }
6378
6379 bool start_array(std::size_t len)
6380 {
6381 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6382 keep_stack.push_back(keep);
6383
6384 auto val = handle_value(BasicJsonType::value_t::array, true);
6385 ref_stack.push_back(val.second);
6386
6387 // check array limit
6388 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6389 {
6390 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6391 }
6392
6393 return true;
6394 }
6395
6397 {
6398 bool keep = true;
6399
6400 if (ref_stack.back())
6401 {
6402 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6403 if (keep)
6404 {
6405 ref_stack.back()->set_parents();
6406 }
6407 else
6408 {
6409 // discard array
6410 *ref_stack.back() = discarded;
6411 }
6412 }
6413
6414 JSON_ASSERT(!ref_stack.empty());
6415 JSON_ASSERT(!keep_stack.empty());
6416 ref_stack.pop_back();
6417 keep_stack.pop_back();
6418
6419 // remove discarded value
6420 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6421 {
6422 ref_stack.back()->m_value.array->pop_back();
6423 }
6424
6425 return true;
6426 }
6427
6428 template<class Exception>
6429 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6430 const Exception& ex)
6431 {
6432 errored = true;
6433 static_cast<void>(ex);
6434 if (allow_exceptions)
6435 {
6436 JSON_THROW(ex);
6437 }
6438 return false;
6439 }
6440
6441 constexpr bool is_errored() const
6442 {
6443 return errored;
6444 }
6445
6446 private:
6462 template<typename Value>
6463 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6464 {
6465 JSON_ASSERT(!keep_stack.empty());
6466
6467 // do not handle this value if we know it would be added to a discarded
6468 // container
6469 if (!keep_stack.back())
6470 {
6471 return {false, nullptr};
6472 }
6473
6474 // create value
6475 auto value = BasicJsonType(std::forward<Value>(v));
6476
6477 // check callback
6478 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6479
6480 // do not handle this value if we just learnt it shall be discarded
6481 if (!keep)
6482 {
6483 return {false, nullptr};
6484 }
6485
6486 if (ref_stack.empty())
6487 {
6488 root = std::move(value);
6489 return {true, &root};
6490 }
6491
6492 // skip this value if we already decided to skip the parent
6493 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6494 if (!ref_stack.back())
6495 {
6496 return {false, nullptr};
6497 }
6498
6499 // we now only expect arrays and objects
6500 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6501
6502 // array
6503 if (ref_stack.back()->is_array())
6504 {
6505 ref_stack.back()->m_value.array->emplace_back(std::move(value));
6506 return {true, &(ref_stack.back()->m_value.array->back())};
6507 }
6508
6509 // object
6510 JSON_ASSERT(ref_stack.back()->is_object());
6511 // check if we should store an element for the current key
6512 JSON_ASSERT(!key_keep_stack.empty());
6513 const bool store_element = key_keep_stack.back();
6514 key_keep_stack.pop_back();
6515
6516 if (!store_element)
6517 {
6518 return {false, nullptr};
6519 }
6520
6521 JSON_ASSERT(object_element);
6522 *object_element = std::move(value);
6523 return {true, object_element};
6524 }
6525
6527 BasicJsonType& root;
6529 std::vector<BasicJsonType*> ref_stack {};
6531 std::vector<bool> keep_stack {};
6533 std::vector<bool> key_keep_stack {};
6535 BasicJsonType* object_element = nullptr;
6537 bool errored = false;
6539 const parser_callback_t callback = nullptr;
6541 const bool allow_exceptions = true;
6543 BasicJsonType discarded = BasicJsonType::value_t::discarded;
6544};
6545
6546template<typename BasicJsonType>
6548{
6549 public:
6550 using number_integer_t = typename BasicJsonType::number_integer_t;
6551 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6552 using number_float_t = typename BasicJsonType::number_float_t;
6553 using string_t = typename BasicJsonType::string_t;
6554 using binary_t = typename BasicJsonType::binary_t;
6555
6556 bool null()
6557 {
6558 return true;
6559 }
6560
6561 bool boolean(bool /*unused*/)
6562 {
6563 return true;
6564 }
6565
6567 {
6568 return true;
6569 }
6570
6572 {
6573 return true;
6574 }
6575
6576 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6577 {
6578 return true;
6579 }
6580
6581 bool string(string_t& /*unused*/)
6582 {
6583 return true;
6584 }
6585
6586 bool binary(binary_t& /*unused*/)
6587 {
6588 return true;
6589 }
6590
6591 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
6592 {
6593 return true;
6594 }
6595
6596 bool key(string_t& /*unused*/)
6597 {
6598 return true;
6599 }
6600
6602 {
6603 return true;
6604 }
6605
6606 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
6607 {
6608 return true;
6609 }
6610
6612 {
6613 return true;
6614 }
6615
6616 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6617 {
6618 return false;
6619 }
6620};
6621} // namespace detail
6622
6623} // namespace nlohmann
6624
6625// #include <nlohmann/detail/input/lexer.hpp>
6626
6627
6628#include <array> // array
6629#include <clocale> // localeconv
6630#include <cstddef> // size_t
6631#include <cstdio> // snprintf
6632#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6633#include <initializer_list> // initializer_list
6634#include <string> // char_traits, string
6635#include <utility> // move
6636#include <vector> // vector
6637
6638// #include <nlohmann/detail/input/input_adapters.hpp>
6639
6640// #include <nlohmann/detail/input/position_t.hpp>
6641
6642// #include <nlohmann/detail/macro_scope.hpp>
6643
6644
6645namespace nlohmann
6646{
6647namespace detail
6648{
6650// lexer //
6652
6653template<typename BasicJsonType>
6655{
6656 public:
6658 enum class token_type
6659 {
6661 literal_true,
6663 literal_null,
6664 value_string,
6667 value_float,
6668 begin_array,
6669 begin_object,
6670 end_array,
6671 end_object,
6674 parse_error,
6675 end_of_input,
6677 };
6678
6682 static const char* token_type_name(const token_type t) noexcept
6683 {
6684 switch (t)
6685 {
6687 return "<uninitialized>";
6689 return "true literal";
6691 return "false literal";
6693 return "null literal";
6695 return "string literal";
6699 return "number literal";
6701 return "'['";
6703 return "'{'";
6705 return "']'";
6707 return "'}'";
6709 return "':'";
6711 return "','";
6713 return "<parse error>";
6715 return "end of input";
6717 return "'[', '{', or a literal";
6718 // LCOV_EXCL_START
6719 default: // catch non-enum values
6720 return "unknown token";
6721 // LCOV_EXCL_STOP
6722 }
6723 }
6724};
6730template<typename BasicJsonType, typename InputAdapterType>
6731class lexer : public lexer_base<BasicJsonType>
6732{
6733 using number_integer_t = typename BasicJsonType::number_integer_t;
6734 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6735 using number_float_t = typename BasicJsonType::number_float_t;
6736 using string_t = typename BasicJsonType::string_t;
6737 using char_type = typename InputAdapterType::char_type;
6738 using char_int_type = typename std::char_traits<char_type>::int_type;
6739
6740 public:
6742
6743 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6744 : ia(std::move(adapter))
6745 , ignore_comments(ignore_comments_)
6747 {}
6748
6749 // delete because of pointer members
6750 lexer(const lexer&) = delete;
6751 lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6752 lexer& operator=(lexer&) = delete;
6753 lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6754 ~lexer() = default;
6755
6756 private:
6758 // locales
6760
6763 static char get_decimal_point() noexcept
6764 {
6765 const auto* loc = localeconv();
6766 JSON_ASSERT(loc != nullptr);
6767 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6768 }
6769
6771 // scan functions
6773
6790 {
6791 // this function only makes sense after reading `\u`
6792 JSON_ASSERT(current == 'u');
6793 int codepoint = 0;
6794
6795 const auto factors = { 12u, 8u, 4u, 0u };
6796 for (const auto factor : factors)
6797 {
6798 get();
6799
6800 if (current >= '0' && current <= '9')
6801 {
6802 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6803 }
6804 else if (current >= 'A' && current <= 'F')
6805 {
6806 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6807 }
6808 else if (current >= 'a' && current <= 'f')
6809 {
6810 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6811 }
6812 else
6813 {
6814 return -1;
6815 }
6816 }
6817
6818 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6819 return codepoint;
6820 }
6821
6837 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6838 {
6839 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6840 add(current);
6841
6842 for (auto range = ranges.begin(); range != ranges.end(); ++range)
6843 {
6844 get();
6845 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6846 {
6847 add(current);
6848 }
6849 else
6850 {
6851 error_message = "invalid string: ill-formed UTF-8 byte";
6852 return false;
6853 }
6854 }
6855
6856 return true;
6857 }
6858
6875 {
6876 // reset token_buffer (ignore opening quote)
6877 reset();
6878
6879 // we entered the function by reading an open quote
6880 JSON_ASSERT(current == '\"');
6881
6882 while (true)
6883 {
6884 // get next character
6885 switch (get())
6886 {
6887 // end of file while parsing string
6888 case std::char_traits<char_type>::eof():
6889 {
6890 error_message = "invalid string: missing closing quote";
6891 return token_type::parse_error;
6892 }
6893
6894 // closing quote
6895 case '\"':
6896 {
6897 return token_type::value_string;
6898 }
6899
6900 // escapes
6901 case '\\':
6902 {
6903 switch (get())
6904 {
6905 // quotation mark
6906 case '\"':
6907 add('\"');
6908 break;
6909 // reverse solidus
6910 case '\\':
6911 add('\\');
6912 break;
6913 // solidus
6914 case '/':
6915 add('/');
6916 break;
6917 // backspace
6918 case 'b':
6919 add('\b');
6920 break;
6921 // form feed
6922 case 'f':
6923 add('\f');
6924 break;
6925 // line feed
6926 case 'n':
6927 add('\n');
6928 break;
6929 // carriage return
6930 case 'r':
6931 add('\r');
6932 break;
6933 // tab
6934 case 't':
6935 add('\t');
6936 break;
6937
6938 // unicode escapes
6939 case 'u':
6940 {
6941 const int codepoint1 = get_codepoint();
6942 int codepoint = codepoint1; // start with codepoint1
6943
6944 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6945 {
6946 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6947 return token_type::parse_error;
6948 }
6949
6950 // check if code point is a high surrogate
6951 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6952 {
6953 // expect next \uxxxx entry
6954 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6955 {
6956 const int codepoint2 = get_codepoint();
6957
6958 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6959 {
6960 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6961 return token_type::parse_error;
6962 }
6963
6964 // check if codepoint2 is a low surrogate
6965 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6966 {
6967 // overwrite codepoint
6968 codepoint = static_cast<int>(
6969 // high surrogate occupies the most significant 22 bits
6970 (static_cast<unsigned int>(codepoint1) << 10u)
6971 // low surrogate occupies the least significant 15 bits
6972 + static_cast<unsigned int>(codepoint2)
6973 // there is still the 0xD800, 0xDC00 and 0x10000 noise
6974 // in the result so we have to subtract with:
6975 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6976 - 0x35FDC00u);
6977 }
6978 else
6979 {
6980 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6981 return token_type::parse_error;
6982 }
6983 }
6984 else
6985 {
6986 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6987 return token_type::parse_error;
6988 }
6989 }
6990 else
6991 {
6992 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6993 {
6994 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6995 return token_type::parse_error;
6996 }
6997 }
6998
6999 // result of the above calculation yields a proper codepoint
7000 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7001
7002 // translate codepoint into bytes
7003 if (codepoint < 0x80)
7004 {
7005 // 1-byte characters: 0xxxxxxx (ASCII)
7006 add(static_cast<char_int_type>(codepoint));
7007 }
7008 else if (codepoint <= 0x7FF)
7009 {
7010 // 2-byte characters: 110xxxxx 10xxxxxx
7011 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7012 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7013 }
7014 else if (codepoint <= 0xFFFF)
7015 {
7016 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7017 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7018 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7019 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7020 }
7021 else
7022 {
7023 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7024 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7025 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7026 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7027 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7028 }
7029
7030 break;
7031 }
7032
7033 // other characters after escape
7034 default:
7035 error_message = "invalid string: forbidden character after backslash";
7036 return token_type::parse_error;
7037 }
7038
7039 break;
7040 }
7041
7042 // invalid control characters
7043 case 0x00:
7044 {
7045 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7046 return token_type::parse_error;
7047 }
7048
7049 case 0x01:
7050 {
7051 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7052 return token_type::parse_error;
7053 }
7054
7055 case 0x02:
7056 {
7057 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7058 return token_type::parse_error;
7059 }
7060
7061 case 0x03:
7062 {
7063 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7064 return token_type::parse_error;
7065 }
7066
7067 case 0x04:
7068 {
7069 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7070 return token_type::parse_error;
7071 }
7072
7073 case 0x05:
7074 {
7075 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7076 return token_type::parse_error;
7077 }
7078
7079 case 0x06:
7080 {
7081 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7082 return token_type::parse_error;
7083 }
7084
7085 case 0x07:
7086 {
7087 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7088 return token_type::parse_error;
7089 }
7090
7091 case 0x08:
7092 {
7093 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7094 return token_type::parse_error;
7095 }
7096
7097 case 0x09:
7098 {
7099 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7100 return token_type::parse_error;
7101 }
7102
7103 case 0x0A:
7104 {
7105 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7106 return token_type::parse_error;
7107 }
7108
7109 case 0x0B:
7110 {
7111 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7112 return token_type::parse_error;
7113 }
7114
7115 case 0x0C:
7116 {
7117 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7118 return token_type::parse_error;
7119 }
7120
7121 case 0x0D:
7122 {
7123 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7124 return token_type::parse_error;
7125 }
7126
7127 case 0x0E:
7128 {
7129 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7130 return token_type::parse_error;
7131 }
7132
7133 case 0x0F:
7134 {
7135 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7136 return token_type::parse_error;
7137 }
7138
7139 case 0x10:
7140 {
7141 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7142 return token_type::parse_error;
7143 }
7144
7145 case 0x11:
7146 {
7147 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7148 return token_type::parse_error;
7149 }
7150
7151 case 0x12:
7152 {
7153 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7154 return token_type::parse_error;
7155 }
7156
7157 case 0x13:
7158 {
7159 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7160 return token_type::parse_error;
7161 }
7162
7163 case 0x14:
7164 {
7165 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7166 return token_type::parse_error;
7167 }
7168
7169 case 0x15:
7170 {
7171 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7172 return token_type::parse_error;
7173 }
7174
7175 case 0x16:
7176 {
7177 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7178 return token_type::parse_error;
7179 }
7180
7181 case 0x17:
7182 {
7183 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7184 return token_type::parse_error;
7185 }
7186
7187 case 0x18:
7188 {
7189 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7190 return token_type::parse_error;
7191 }
7192
7193 case 0x19:
7194 {
7195 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7196 return token_type::parse_error;
7197 }
7198
7199 case 0x1A:
7200 {
7201 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7202 return token_type::parse_error;
7203 }
7204
7205 case 0x1B:
7206 {
7207 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7208 return token_type::parse_error;
7209 }
7210
7211 case 0x1C:
7212 {
7213 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7214 return token_type::parse_error;
7215 }
7216
7217 case 0x1D:
7218 {
7219 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7220 return token_type::parse_error;
7221 }
7222
7223 case 0x1E:
7224 {
7225 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7226 return token_type::parse_error;
7227 }
7228
7229 case 0x1F:
7230 {
7231 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7232 return token_type::parse_error;
7233 }
7234
7235 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7236 case 0x20:
7237 case 0x21:
7238 case 0x23:
7239 case 0x24:
7240 case 0x25:
7241 case 0x26:
7242 case 0x27:
7243 case 0x28:
7244 case 0x29:
7245 case 0x2A:
7246 case 0x2B:
7247 case 0x2C:
7248 case 0x2D:
7249 case 0x2E:
7250 case 0x2F:
7251 case 0x30:
7252 case 0x31:
7253 case 0x32:
7254 case 0x33:
7255 case 0x34:
7256 case 0x35:
7257 case 0x36:
7258 case 0x37:
7259 case 0x38:
7260 case 0x39:
7261 case 0x3A:
7262 case 0x3B:
7263 case 0x3C:
7264 case 0x3D:
7265 case 0x3E:
7266 case 0x3F:
7267 case 0x40:
7268 case 0x41:
7269 case 0x42:
7270 case 0x43:
7271 case 0x44:
7272 case 0x45:
7273 case 0x46:
7274 case 0x47:
7275 case 0x48:
7276 case 0x49:
7277 case 0x4A:
7278 case 0x4B:
7279 case 0x4C:
7280 case 0x4D:
7281 case 0x4E:
7282 case 0x4F:
7283 case 0x50:
7284 case 0x51:
7285 case 0x52:
7286 case 0x53:
7287 case 0x54:
7288 case 0x55:
7289 case 0x56:
7290 case 0x57:
7291 case 0x58:
7292 case 0x59:
7293 case 0x5A:
7294 case 0x5B:
7295 case 0x5D:
7296 case 0x5E:
7297 case 0x5F:
7298 case 0x60:
7299 case 0x61:
7300 case 0x62:
7301 case 0x63:
7302 case 0x64:
7303 case 0x65:
7304 case 0x66:
7305 case 0x67:
7306 case 0x68:
7307 case 0x69:
7308 case 0x6A:
7309 case 0x6B:
7310 case 0x6C:
7311 case 0x6D:
7312 case 0x6E:
7313 case 0x6F:
7314 case 0x70:
7315 case 0x71:
7316 case 0x72:
7317 case 0x73:
7318 case 0x74:
7319 case 0x75:
7320 case 0x76:
7321 case 0x77:
7322 case 0x78:
7323 case 0x79:
7324 case 0x7A:
7325 case 0x7B:
7326 case 0x7C:
7327 case 0x7D:
7328 case 0x7E:
7329 case 0x7F:
7330 {
7331 add(current);
7332 break;
7333 }
7334
7335 // U+0080..U+07FF: bytes C2..DF 80..BF
7336 case 0xC2:
7337 case 0xC3:
7338 case 0xC4:
7339 case 0xC5:
7340 case 0xC6:
7341 case 0xC7:
7342 case 0xC8:
7343 case 0xC9:
7344 case 0xCA:
7345 case 0xCB:
7346 case 0xCC:
7347 case 0xCD:
7348 case 0xCE:
7349 case 0xCF:
7350 case 0xD0:
7351 case 0xD1:
7352 case 0xD2:
7353 case 0xD3:
7354 case 0xD4:
7355 case 0xD5:
7356 case 0xD6:
7357 case 0xD7:
7358 case 0xD8:
7359 case 0xD9:
7360 case 0xDA:
7361 case 0xDB:
7362 case 0xDC:
7363 case 0xDD:
7364 case 0xDE:
7365 case 0xDF:
7366 {
7367 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7368 {
7369 return token_type::parse_error;
7370 }
7371 break;
7372 }
7373
7374 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7375 case 0xE0:
7376 {
7377 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7378 {
7379 return token_type::parse_error;
7380 }
7381 break;
7382 }
7383
7384 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7385 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7386 case 0xE1:
7387 case 0xE2:
7388 case 0xE3:
7389 case 0xE4:
7390 case 0xE5:
7391 case 0xE6:
7392 case 0xE7:
7393 case 0xE8:
7394 case 0xE9:
7395 case 0xEA:
7396 case 0xEB:
7397 case 0xEC:
7398 case 0xEE:
7399 case 0xEF:
7400 {
7401 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7402 {
7403 return token_type::parse_error;
7404 }
7405 break;
7406 }
7407
7408 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7409 case 0xED:
7410 {
7411 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7412 {
7413 return token_type::parse_error;
7414 }
7415 break;
7416 }
7417
7418 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7419 case 0xF0:
7420 {
7421 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7422 {
7423 return token_type::parse_error;
7424 }
7425 break;
7426 }
7427
7428 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7429 case 0xF1:
7430 case 0xF2:
7431 case 0xF3:
7432 {
7433 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7434 {
7435 return token_type::parse_error;
7436 }
7437 break;
7438 }
7439
7440 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7441 case 0xF4:
7442 {
7443 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7444 {
7445 return token_type::parse_error;
7446 }
7447 break;
7448 }
7449
7450 // remaining bytes (80..C1 and F5..FF) are ill-formed
7451 default:
7452 {
7453 error_message = "invalid string: ill-formed UTF-8 byte";
7454 return token_type::parse_error;
7455 }
7456 }
7457 }
7458 }
7459
7465 {
7466 switch (get())
7467 {
7468 // single-line comments skip input until a newline or EOF is read
7469 case '/':
7470 {
7471 while (true)
7472 {
7473 switch (get())
7474 {
7475 case '\n':
7476 case '\r':
7477 case std::char_traits<char_type>::eof():
7478 case '\0':
7479 return true;
7480
7481 default:
7482 break;
7483 }
7484 }
7485 }
7486
7487 // multi-line comments skip input until */ is read
7488 case '*':
7489 {
7490 while (true)
7491 {
7492 switch (get())
7493 {
7494 case std::char_traits<char_type>::eof():
7495 case '\0':
7496 {
7497 error_message = "invalid comment; missing closing '*/'";
7498 return false;
7499 }
7500
7501 case '*':
7502 {
7503 switch (get())
7504 {
7505 case '/':
7506 return true;
7507
7508 default:
7509 {
7510 unget();
7511 continue;
7512 }
7513 }
7514 }
7515
7516 default:
7517 continue;
7518 }
7519 }
7520 }
7521
7522 // unexpected character after reading '/'
7523 default:
7524 {
7525 error_message = "invalid comment; expecting '/' or '*' after '/'";
7526 return false;
7527 }
7528 }
7529 }
7530
7532 static void strtof(float& f, const char* str, char** endptr) noexcept
7533 {
7534 f = std::strtof(str, endptr);
7535 }
7536
7538 static void strtof(double& f, const char* str, char** endptr) noexcept
7539 {
7540 f = std::strtod(str, endptr);
7541 }
7542
7544 static void strtof(long double& f, const char* str, char** endptr) noexcept
7545 {
7546 f = std::strtold(str, endptr);
7547 }
7548
7589 token_type scan_number() // lgtm [cpp/use-of-goto]
7590 {
7591 // reset token_buffer to store the number's bytes
7592 reset();
7593
7594 // the type of the parsed number; initially set to unsigned; will be
7595 // changed if minus sign, decimal point or exponent is read
7596 token_type number_type = token_type::value_unsigned;
7597
7598 // state (init): we just found out we need to scan a number
7599 switch (current)
7600 {
7601 case '-':
7602 {
7603 add(current);
7604 goto scan_number_minus;
7605 }
7606
7607 case '0':
7608 {
7609 add(current);
7610 goto scan_number_zero;
7611 }
7612
7613 case '1':
7614 case '2':
7615 case '3':
7616 case '4':
7617 case '5':
7618 case '6':
7619 case '7':
7620 case '8':
7621 case '9':
7622 {
7623 add(current);
7624 goto scan_number_any1;
7625 }
7626
7627 // all other characters are rejected outside scan_number()
7628 default: // LCOV_EXCL_LINE
7629 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7630 }
7631
7632scan_number_minus:
7633 // state: we just parsed a leading minus sign
7634 number_type = token_type::value_integer;
7635 switch (get())
7636 {
7637 case '0':
7638 {
7639 add(current);
7640 goto scan_number_zero;
7641 }
7642
7643 case '1':
7644 case '2':
7645 case '3':
7646 case '4':
7647 case '5':
7648 case '6':
7649 case '7':
7650 case '8':
7651 case '9':
7652 {
7653 add(current);
7654 goto scan_number_any1;
7655 }
7656
7657 default:
7658 {
7659 error_message = "invalid number; expected digit after '-'";
7660 return token_type::parse_error;
7661 }
7662 }
7663
7664scan_number_zero:
7665 // state: we just parse a zero (maybe with a leading minus sign)
7666 switch (get())
7667 {
7668 case '.':
7669 {
7671 goto scan_number_decimal1;
7672 }
7673
7674 case 'e':
7675 case 'E':
7676 {
7677 add(current);
7678 goto scan_number_exponent;
7679 }
7680
7681 default:
7682 goto scan_number_done;
7683 }
7684
7685scan_number_any1:
7686 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7687 switch (get())
7688 {
7689 case '0':
7690 case '1':
7691 case '2':
7692 case '3':
7693 case '4':
7694 case '5':
7695 case '6':
7696 case '7':
7697 case '8':
7698 case '9':
7699 {
7700 add(current);
7701 goto scan_number_any1;
7702 }
7703
7704 case '.':
7705 {
7707 goto scan_number_decimal1;
7708 }
7709
7710 case 'e':
7711 case 'E':
7712 {
7713 add(current);
7714 goto scan_number_exponent;
7715 }
7716
7717 default:
7718 goto scan_number_done;
7719 }
7720
7721scan_number_decimal1:
7722 // state: we just parsed a decimal point
7723 number_type = token_type::value_float;
7724 switch (get())
7725 {
7726 case '0':
7727 case '1':
7728 case '2':
7729 case '3':
7730 case '4':
7731 case '5':
7732 case '6':
7733 case '7':
7734 case '8':
7735 case '9':
7736 {
7737 add(current);
7738 goto scan_number_decimal2;
7739 }
7740
7741 default:
7742 {
7743 error_message = "invalid number; expected digit after '.'";
7744 return token_type::parse_error;
7745 }
7746 }
7747
7748scan_number_decimal2:
7749 // we just parsed at least one number after a decimal point
7750 switch (get())
7751 {
7752 case '0':
7753 case '1':
7754 case '2':
7755 case '3':
7756 case '4':
7757 case '5':
7758 case '6':
7759 case '7':
7760 case '8':
7761 case '9':
7762 {
7763 add(current);
7764 goto scan_number_decimal2;
7765 }
7766
7767 case 'e':
7768 case 'E':
7769 {
7770 add(current);
7771 goto scan_number_exponent;
7772 }
7773
7774 default:
7775 goto scan_number_done;
7776 }
7777
7778scan_number_exponent:
7779 // we just parsed an exponent
7780 number_type = token_type::value_float;
7781 switch (get())
7782 {
7783 case '+':
7784 case '-':
7785 {
7786 add(current);
7787 goto scan_number_sign;
7788 }
7789
7790 case '0':
7791 case '1':
7792 case '2':
7793 case '3':
7794 case '4':
7795 case '5':
7796 case '6':
7797 case '7':
7798 case '8':
7799 case '9':
7800 {
7801 add(current);
7802 goto scan_number_any2;
7803 }
7804
7805 default:
7806 {
7808 "invalid number; expected '+', '-', or digit after exponent";
7809 return token_type::parse_error;
7810 }
7811 }
7812
7813scan_number_sign:
7814 // we just parsed an exponent sign
7815 switch (get())
7816 {
7817 case '0':
7818 case '1':
7819 case '2':
7820 case '3':
7821 case '4':
7822 case '5':
7823 case '6':
7824 case '7':
7825 case '8':
7826 case '9':
7827 {
7828 add(current);
7829 goto scan_number_any2;
7830 }
7831
7832 default:
7833 {
7834 error_message = "invalid number; expected digit after exponent sign";
7835 return token_type::parse_error;
7836 }
7837 }
7838
7839scan_number_any2:
7840 // we just parsed a number after the exponent or exponent sign
7841 switch (get())
7842 {
7843 case '0':
7844 case '1':
7845 case '2':
7846 case '3':
7847 case '4':
7848 case '5':
7849 case '6':
7850 case '7':
7851 case '8':
7852 case '9':
7853 {
7854 add(current);
7855 goto scan_number_any2;
7856 }
7857
7858 default:
7859 goto scan_number_done;
7860 }
7861
7862scan_number_done:
7863 // unget the character after the number (we only read it to know that
7864 // we are done scanning a number)
7865 unget();
7866
7867 char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7868 errno = 0;
7869
7870 // try to parse integers first and fall back to floats
7871 if (number_type == token_type::value_unsigned)
7872 {
7873 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7874
7875 // we checked the number format before
7876 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7877
7878 if (errno == 0)
7879 {
7880 value_unsigned = static_cast<number_unsigned_t>(x);
7881 if (value_unsigned == x)
7882 {
7883 return token_type::value_unsigned;
7884 }
7885 }
7886 }
7887 else if (number_type == token_type::value_integer)
7888 {
7889 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7890
7891 // we checked the number format before
7892 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7893
7894 if (errno == 0)
7895 {
7896 value_integer = static_cast<number_integer_t>(x);
7897 if (value_integer == x)
7898 {
7899 return token_type::value_integer;
7900 }
7901 }
7902 }
7903
7904 // this code is reached if we parse a floating-point number or if an
7905 // integer conversion above failed
7906 strtof(value_float, token_buffer.data(), &endptr);
7907
7908 // we checked the number format before
7909 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7910
7911 return token_type::value_float;
7912 }
7913
7920 token_type scan_literal(const char_type* literal_text, const std::size_t length,
7921 token_type return_type)
7922 {
7923 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7924 for (std::size_t i = 1; i < length; ++i)
7925 {
7926 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7927 {
7928 error_message = "invalid literal";
7929 return token_type::parse_error;
7930 }
7931 }
7932 return return_type;
7933 }
7934
7936 // input management
7938
7940 void reset() noexcept
7941 {
7942 token_buffer.clear();
7943 token_string.clear();
7944 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7945 }
7946
7947 /*
7948 @brief get next character from the input
7949
7950 This function provides the interface to the used input adapter. It does
7951 not throw in case the input reached EOF, but returns a
7952 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
7953 for use in error messages.
7954
7955 @return character read from the input
7956 */
7958 {
7961
7962 if (next_unget)
7963 {
7964 // just reset the next_unget variable and work with current
7965 next_unget = false;
7966 }
7967 else
7968 {
7969 current = ia.get_character();
7970 }
7971
7972 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7973 {
7974 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7975 }
7976
7977 if (current == '\n')
7978 {
7981 }
7982
7983 return current;
7984 }
7985
7994 void unget()
7995 {
7996 next_unget = true;
7997
7999
8000 // in case we "unget" a newline, we have to also decrement the lines_read
8002 {
8003 if (position.lines_read > 0)
8004 {
8006 }
8007 }
8008 else
8009 {
8011 }
8012
8013 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8014 {
8015 JSON_ASSERT(!token_string.empty());
8016 token_string.pop_back();
8017 }
8018 }
8019
8022 {
8023 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8024 }
8025
8026 public:
8028 // value getters
8030
8032 constexpr number_integer_t get_number_integer() const noexcept
8033 {
8034 return value_integer;
8035 }
8036
8038 constexpr number_unsigned_t get_number_unsigned() const noexcept
8039 {
8040 return value_unsigned;
8041 }
8042
8044 constexpr number_float_t get_number_float() const noexcept
8045 {
8046 return value_float;
8047 }
8048
8051 {
8052 return token_buffer;
8053 }
8054
8056 // diagnostics
8058
8060 constexpr position_t get_position() const noexcept
8061 {
8062 return position;
8063 }
8064
8068 std::string get_token_string() const
8069 {
8070 // escape control characters
8071 std::string result;
8072 for (const auto c : token_string)
8073 {
8074 if (static_cast<unsigned char>(c) <= '\x1F')
8075 {
8076 // escape control characters
8077 std::array<char, 9> cs{{}};
8078 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8079 result += cs.data();
8080 }
8081 else
8082 {
8083 // add character as is
8084 result.push_back(static_cast<std::string::value_type>(c));
8085 }
8086 }
8087
8088 return result;
8089 }
8090
8093 constexpr const char* get_error_message() const noexcept
8094 {
8095 return error_message;
8096 }
8097
8099 // actual scanner
8101
8107 {
8108 if (get() == 0xEF)
8109 {
8110 // check if we completely parse the BOM
8111 return get() == 0xBB && get() == 0xBF;
8112 }
8113
8114 // the first character is not the beginning of the BOM; unget it to
8115 // process is later
8116 unget();
8117 return true;
8118 }
8119
8121 {
8122 do
8123 {
8124 get();
8125 }
8126 while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8127 }
8128
8130 {
8131 // initially, skip the BOM
8132 if (position.chars_read_total == 0 && !skip_bom())
8133 {
8134 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8135 return token_type::parse_error;
8136 }
8137
8138 // read next character and ignore whitespace
8140
8141 // ignore comments
8142 while (ignore_comments && current == '/')
8143 {
8144 if (!scan_comment())
8145 {
8146 return token_type::parse_error;
8147 }
8148
8149 // skip following whitespace
8151 }
8152
8153 switch (current)
8154 {
8155 // structural characters
8156 case '[':
8157 return token_type::begin_array;
8158 case ']':
8159 return token_type::end_array;
8160 case '{':
8161 return token_type::begin_object;
8162 case '}':
8163 return token_type::end_object;
8164 case ':':
8165 return token_type::name_separator;
8166 case ',':
8167 return token_type::value_separator;
8168
8169 // literals
8170 case 't':
8171 {
8172 std::array<char_type, 4> true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}};
8173 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8174 }
8175 case 'f':
8176 {
8177 std::array<char_type, 5> false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}};
8178 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8179 }
8180 case 'n':
8181 {
8182 std::array<char_type, 4> null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}};
8183 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8184 }
8185
8186 // string
8187 case '\"':
8188 return scan_string();
8189
8190 // number
8191 case '-':
8192 case '0':
8193 case '1':
8194 case '2':
8195 case '3':
8196 case '4':
8197 case '5':
8198 case '6':
8199 case '7':
8200 case '8':
8201 case '9':
8202 return scan_number();
8203
8204 // end of input (the null byte is needed when parsing from
8205 // string literals)
8206 case '\0':
8207 case std::char_traits<char_type>::eof():
8208 return token_type::end_of_input;
8209
8210 // error
8211 default:
8212 error_message = "invalid literal";
8213 return token_type::parse_error;
8214 }
8215 }
8216
8217 private:
8219 InputAdapterType ia;
8220
8222 const bool ignore_comments = false;
8223
8225 char_int_type current = std::char_traits<char_type>::eof();
8226
8228 bool next_unget = false;
8229
8232
8234 std::vector<char_type> token_string {};
8235
8238
8240 const char* error_message = "";
8241
8242 // number values
8246
8249};
8250} // namespace detail
8251} // namespace nlohmann
8252
8253// #include <nlohmann/detail/macro_scope.hpp>
8254
8255// #include <nlohmann/detail/meta/is_sax.hpp>
8256
8257
8258#include <cstdint> // size_t
8259#include <utility> // declval
8260#include <string> // string
8261
8262// #include <nlohmann/detail/meta/detected.hpp>
8263
8264// #include <nlohmann/detail/meta/type_traits.hpp>
8265
8266
8267namespace nlohmann
8268{
8269namespace detail
8270{
8271template<typename T>
8272using null_function_t = decltype(std::declval<T&>().null());
8273
8274template<typename T>
8276 decltype(std::declval<T&>().boolean(std::declval<bool>()));
8277
8278template<typename T, typename Integer>
8280 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8281
8282template<typename T, typename Unsigned>
8284 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8285
8286template<typename T, typename Float, typename String>
8287using number_float_function_t = decltype(std::declval<T&>().number_float(
8288 std::declval<Float>(), std::declval<const String&>()));
8289
8290template<typename T, typename String>
8292 decltype(std::declval<T&>().string(std::declval<String&>()));
8293
8294template<typename T, typename Binary>
8296 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8297
8298template<typename T>
8300 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8301
8302template<typename T, typename String>
8304 decltype(std::declval<T&>().key(std::declval<String&>()));
8305
8306template<typename T>
8307using end_object_function_t = decltype(std::declval<T&>().end_object());
8308
8309template<typename T>
8311 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8312
8313template<typename T>
8314using end_array_function_t = decltype(std::declval<T&>().end_array());
8315
8316template<typename T, typename Exception>
8317using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8318 std::declval<std::size_t>(), std::declval<const std::string&>(),
8319 std::declval<const Exception&>()));
8320
8321template<typename SAX, typename BasicJsonType>
8323{
8324 private:
8326 "BasicJsonType must be of type basic_json<...>");
8327
8328 using number_integer_t = typename BasicJsonType::number_integer_t;
8329 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8330 using number_float_t = typename BasicJsonType::number_float_t;
8331 using string_t = typename BasicJsonType::string_t;
8332 using binary_t = typename BasicJsonType::binary_t;
8333 using exception_t = typename BasicJsonType::exception;
8334
8335 public:
8336 static constexpr bool value =
8350};
8351
8352template<typename SAX, typename BasicJsonType>
8354{
8355 private:
8357 "BasicJsonType must be of type basic_json<...>");
8358
8359 using number_integer_t = typename BasicJsonType::number_integer_t;
8360 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8361 using number_float_t = typename BasicJsonType::number_float_t;
8362 using string_t = typename BasicJsonType::string_t;
8363 using binary_t = typename BasicJsonType::binary_t;
8364 using exception_t = typename BasicJsonType::exception;
8365
8366 public:
8368 "Missing/invalid function: bool null()");
8370 "Missing/invalid function: bool boolean(bool)");
8372 "Missing/invalid function: bool boolean(bool)");
8373 static_assert(
8376 "Missing/invalid function: bool number_integer(number_integer_t)");
8377 static_assert(
8380 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8381 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8383 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8384 static_assert(
8386 "Missing/invalid function: bool string(string_t&)");
8387 static_assert(
8389 "Missing/invalid function: bool binary(binary_t&)");
8391 "Missing/invalid function: bool start_object(std::size_t)");
8393 "Missing/invalid function: bool key(string_t&)");
8395 "Missing/invalid function: bool end_object()");
8397 "Missing/invalid function: bool start_array(std::size_t)");
8399 "Missing/invalid function: bool end_array()");
8400 static_assert(
8402 "Missing/invalid function: bool parse_error(std::size_t, const "
8403 "std::string&, const exception&)");
8404};
8405} // namespace detail
8406} // namespace nlohmann
8407
8408// #include <nlohmann/detail/meta/type_traits.hpp>
8409
8410// #include <nlohmann/detail/value_t.hpp>
8411
8412
8413namespace nlohmann
8414{
8415namespace detail
8416{
8417
8420{
8421 error,
8422 ignore,
8423 store
8424};
8425
8433static inline bool little_endianness(int num = 1) noexcept
8434{
8435 return *reinterpret_cast<char*>(&num) == 1;
8436}
8437
8438
8440// binary reader //
8442
8446template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8448{
8449 using number_integer_t = typename BasicJsonType::number_integer_t;
8450 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8451 using number_float_t = typename BasicJsonType::number_float_t;
8452 using string_t = typename BasicJsonType::string_t;
8453 using binary_t = typename BasicJsonType::binary_t;
8454 using json_sax_t = SAX;
8455 using char_type = typename InputAdapterType::char_type;
8456 using char_int_type = typename std::char_traits<char_type>::int_type;
8457
8458 public:
8464 explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))
8465 {
8467 }
8468
8469 // make class move-only
8471 binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8473 binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8474 ~binary_reader() = default;
8475
8485 bool sax_parse(const input_format_t format,
8486 json_sax_t* sax_,
8487 const bool strict = true,
8488 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8489 {
8490 sax = sax_;
8491 bool result = false;
8492
8493 switch (format)
8494 {
8496 result = parse_bson_internal();
8497 break;
8498
8500 result = parse_cbor_internal(true, tag_handler);
8501 break;
8502
8504 result = parse_msgpack_internal();
8505 break;
8506
8508 result = parse_ubjson_internal();
8509 break;
8510
8511 case input_format_t::json: // LCOV_EXCL_LINE
8512 default: // LCOV_EXCL_LINE
8513 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8514 }
8515
8516 // strict mode: next byte must be EOF
8517 if (result && strict)
8518 {
8519 if (format == input_format_t::ubjson)
8520 {
8522 }
8523 else
8524 {
8525 get();
8526 }
8527
8528 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8529 {
8530 return sax->parse_error(chars_read, get_token_string(),
8531 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType()));
8532 }
8533 }
8534
8535 return result;
8536 }
8537
8538 private:
8540 // BSON //
8542
8548 {
8549 std::int32_t document_size{};
8550 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8551
8552 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
8553 {
8554 return false;
8555 }
8556
8557 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8558 {
8559 return false;
8560 }
8561
8562 return sax->end_object();
8563 }
8564
8573 {
8574 auto out = std::back_inserter(result);
8575 while (true)
8576 {
8577 get();
8579 {
8580 return false;
8581 }
8582 if (current == 0x00)
8583 {
8584 return true;
8585 }
8586 *out++ = static_cast<typename string_t::value_type>(current);
8587 }
8588 }
8589
8601 template<typename NumberType>
8602 bool get_bson_string(const NumberType len, string_t& result)
8603 {
8604 if (JSON_HEDLEY_UNLIKELY(len < 1))
8605 {
8606 auto last_token = get_token_string();
8607 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string"), BasicJsonType()));
8608 }
8609
8610 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8611 }
8612
8622 template<typename NumberType>
8623 bool get_bson_binary(const NumberType len, binary_t& result)
8624 {
8625 if (JSON_HEDLEY_UNLIKELY(len < 0))
8626 {
8627 auto last_token = get_token_string();
8628 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary"), BasicJsonType()));
8629 }
8630
8631 // All BSON binary values have a subtype
8632 std::uint8_t subtype{};
8633 get_number<std::uint8_t>(input_format_t::bson, subtype);
8634 result.set_subtype(subtype);
8635
8636 return get_binary(input_format_t::bson, len, result);
8637 }
8638
8650 const std::size_t element_type_parse_position)
8651 {
8652 switch (element_type)
8653 {
8654 case 0x01: // double
8655 {
8656 double number{};
8657 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8658 }
8659
8660 case 0x02: // string
8661 {
8662 std::int32_t len{};
8664 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8665 }
8666
8667 case 0x03: // object
8668 {
8669 return parse_bson_internal();
8670 }
8671
8672 case 0x04: // array
8673 {
8674 return parse_bson_array();
8675 }
8676
8677 case 0x05: // binary
8678 {
8679 std::int32_t len{};
8681 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
8682 }
8683
8684 case 0x08: // boolean
8685 {
8686 return sax->boolean(get() != 0);
8687 }
8688
8689 case 0x0A: // null
8690 {
8691 return sax->null();
8692 }
8693
8694 case 0x10: // int32
8695 {
8696 std::int32_t value{};
8697 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8698 }
8699
8700 case 0x12: // int64
8701 {
8702 std::int64_t value{};
8703 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8704 }
8705
8706 default: // anything else not supported (yet)
8707 {
8708 std::array<char, 3> cr{{}};
8709 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8710 return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data()), BasicJsonType()));
8711 }
8712 }
8713 }
8714
8727 bool parse_bson_element_list(const bool is_array)
8728 {
8729 string_t key;
8730
8731 while (auto element_type = get())
8732 {
8734 {
8735 return false;
8736 }
8737
8738 const std::size_t element_type_parse_position = chars_read;
8740 {
8741 return false;
8742 }
8743
8744 if (!is_array && !sax->key(key))
8745 {
8746 return false;
8747 }
8748
8749 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8750 {
8751 return false;
8752 }
8753
8754 // get_bson_cstr only appends
8755 key.clear();
8756 }
8757
8758 return true;
8759 }
8760
8766 {
8767 std::int32_t document_size{};
8768 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8769
8770 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8771 {
8772 return false;
8773 }
8774
8775 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8776 {
8777 return false;
8778 }
8779
8780 return sax->end_array();
8781 }
8782
8784 // CBOR //
8786
8795 bool parse_cbor_internal(const bool get_char,
8796 const cbor_tag_handler_t tag_handler)
8797 {
8798 switch (get_char ? get() : current)
8799 {
8800 // EOF
8801 case std::char_traits<char_type>::eof():
8802 return unexpect_eof(input_format_t::cbor, "value");
8803
8804 // Integer 0x00..0x17 (0..23)
8805 case 0x00:
8806 case 0x01:
8807 case 0x02:
8808 case 0x03:
8809 case 0x04:
8810 case 0x05:
8811 case 0x06:
8812 case 0x07:
8813 case 0x08:
8814 case 0x09:
8815 case 0x0A:
8816 case 0x0B:
8817 case 0x0C:
8818 case 0x0D:
8819 case 0x0E:
8820 case 0x0F:
8821 case 0x10:
8822 case 0x11:
8823 case 0x12:
8824 case 0x13:
8825 case 0x14:
8826 case 0x15:
8827 case 0x16:
8828 case 0x17:
8829 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8830
8831 case 0x18: // Unsigned integer (one-byte uint8_t follows)
8832 {
8833 std::uint8_t number{};
8834 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8835 }
8836
8837 case 0x19: // Unsigned integer (two-byte uint16_t follows)
8838 {
8839 std::uint16_t number{};
8840 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8841 }
8842
8843 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8844 {
8845 std::uint32_t number{};
8846 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8847 }
8848
8849 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8850 {
8851 std::uint64_t number{};
8852 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8853 }
8854
8855 // Negative integer -1-0x00..-1-0x17 (-1..-24)
8856 case 0x20:
8857 case 0x21:
8858 case 0x22:
8859 case 0x23:
8860 case 0x24:
8861 case 0x25:
8862 case 0x26:
8863 case 0x27:
8864 case 0x28:
8865 case 0x29:
8866 case 0x2A:
8867 case 0x2B:
8868 case 0x2C:
8869 case 0x2D:
8870 case 0x2E:
8871 case 0x2F:
8872 case 0x30:
8873 case 0x31:
8874 case 0x32:
8875 case 0x33:
8876 case 0x34:
8877 case 0x35:
8878 case 0x36:
8879 case 0x37:
8880 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8881
8882 case 0x38: // Negative integer (one-byte uint8_t follows)
8883 {
8884 std::uint8_t number{};
8885 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8886 }
8887
8888 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8889 {
8890 std::uint16_t number{};
8891 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8892 }
8893
8894 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8895 {
8896 std::uint32_t number{};
8897 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8898 }
8899
8900 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8901 {
8902 std::uint64_t number{};
8903 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8904 - static_cast<number_integer_t>(number));
8905 }
8906
8907 // Binary data (0x00..0x17 bytes follow)
8908 case 0x40:
8909 case 0x41:
8910 case 0x42:
8911 case 0x43:
8912 case 0x44:
8913 case 0x45:
8914 case 0x46:
8915 case 0x47:
8916 case 0x48:
8917 case 0x49:
8918 case 0x4A:
8919 case 0x4B:
8920 case 0x4C:
8921 case 0x4D:
8922 case 0x4E:
8923 case 0x4F:
8924 case 0x50:
8925 case 0x51:
8926 case 0x52:
8927 case 0x53:
8928 case 0x54:
8929 case 0x55:
8930 case 0x56:
8931 case 0x57:
8932 case 0x58: // Binary data (one-byte uint8_t for n follows)
8933 case 0x59: // Binary data (two-byte uint16_t for n follow)
8934 case 0x5A: // Binary data (four-byte uint32_t for n follow)
8935 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8936 case 0x5F: // Binary data (indefinite length)
8937 {
8938 binary_t b;
8939 return get_cbor_binary(b) && sax->binary(b);
8940 }
8941
8942 // UTF-8 string (0x00..0x17 bytes follow)
8943 case 0x60:
8944 case 0x61:
8945 case 0x62:
8946 case 0x63:
8947 case 0x64:
8948 case 0x65:
8949 case 0x66:
8950 case 0x67:
8951 case 0x68:
8952 case 0x69:
8953 case 0x6A:
8954 case 0x6B:
8955 case 0x6C:
8956 case 0x6D:
8957 case 0x6E:
8958 case 0x6F:
8959 case 0x70:
8960 case 0x71:
8961 case 0x72:
8962 case 0x73:
8963 case 0x74:
8964 case 0x75:
8965 case 0x76:
8966 case 0x77:
8967 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8968 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8969 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8970 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8971 case 0x7F: // UTF-8 string (indefinite length)
8972 {
8973 string_t s;
8974 return get_cbor_string(s) && sax->string(s);
8975 }
8976
8977 // array (0x00..0x17 data items follow)
8978 case 0x80:
8979 case 0x81:
8980 case 0x82:
8981 case 0x83:
8982 case 0x84:
8983 case 0x85:
8984 case 0x86:
8985 case 0x87:
8986 case 0x88:
8987 case 0x89:
8988 case 0x8A:
8989 case 0x8B:
8990 case 0x8C:
8991 case 0x8D:
8992 case 0x8E:
8993 case 0x8F:
8994 case 0x90:
8995 case 0x91:
8996 case 0x92:
8997 case 0x93:
8998 case 0x94:
8999 case 0x95:
9000 case 0x96:
9001 case 0x97:
9002 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9003
9004 case 0x98: // array (one-byte uint8_t for n follows)
9005 {
9006 std::uint8_t len{};
9007 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9008 }
9009
9010 case 0x99: // array (two-byte uint16_t for n follow)
9011 {
9012 std::uint16_t len{};
9013 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9014 }
9015
9016 case 0x9A: // array (four-byte uint32_t for n follow)
9017 {
9018 std::uint32_t len{};
9019 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9020 }
9021
9022 case 0x9B: // array (eight-byte uint64_t for n follow)
9023 {
9024 std::uint64_t len{};
9025 return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9026 }
9027
9028 case 0x9F: // array (indefinite length)
9029 return get_cbor_array(std::size_t(-1), tag_handler);
9030
9031 // map (0x00..0x17 pairs of data items follow)
9032 case 0xA0:
9033 case 0xA1:
9034 case 0xA2:
9035 case 0xA3:
9036 case 0xA4:
9037 case 0xA5:
9038 case 0xA6:
9039 case 0xA7:
9040 case 0xA8:
9041 case 0xA9:
9042 case 0xAA:
9043 case 0xAB:
9044 case 0xAC:
9045 case 0xAD:
9046 case 0xAE:
9047 case 0xAF:
9048 case 0xB0:
9049 case 0xB1:
9050 case 0xB2:
9051 case 0xB3:
9052 case 0xB4:
9053 case 0xB5:
9054 case 0xB6:
9055 case 0xB7:
9056 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9057
9058 case 0xB8: // map (one-byte uint8_t for n follows)
9059 {
9060 std::uint8_t len{};
9061 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9062 }
9063
9064 case 0xB9: // map (two-byte uint16_t for n follow)
9065 {
9066 std::uint16_t len{};
9067 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9068 }
9069
9070 case 0xBA: // map (four-byte uint32_t for n follow)
9071 {
9072 std::uint32_t len{};
9073 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9074 }
9075
9076 case 0xBB: // map (eight-byte uint64_t for n follow)
9077 {
9078 std::uint64_t len{};
9079 return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9080 }
9081
9082 case 0xBF: // map (indefinite length)
9083 return get_cbor_object(std::size_t(-1), tag_handler);
9084
9085 case 0xC6: // tagged item
9086 case 0xC7:
9087 case 0xC8:
9088 case 0xC9:
9089 case 0xCA:
9090 case 0xCB:
9091 case 0xCC:
9092 case 0xCD:
9093 case 0xCE:
9094 case 0xCF:
9095 case 0xD0:
9096 case 0xD1:
9097 case 0xD2:
9098 case 0xD3:
9099 case 0xD4:
9100 case 0xD8: // tagged item (1 bytes follow)
9101 case 0xD9: // tagged item (2 bytes follow)
9102 case 0xDA: // tagged item (4 bytes follow)
9103 case 0xDB: // tagged item (8 bytes follow)
9104 {
9105 switch (tag_handler)
9106 {
9108 {
9109 auto last_token = get_token_string();
9110 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9111 }
9112
9114 {
9115 // ignore binary subtype
9116 switch (current)
9117 {
9118 case 0xD8:
9119 {
9120 std::uint8_t subtype_to_ignore{};
9121 get_number(input_format_t::cbor, subtype_to_ignore);
9122 break;
9123 }
9124 case 0xD9:
9125 {
9126 std::uint16_t subtype_to_ignore{};
9127 get_number(input_format_t::cbor, subtype_to_ignore);
9128 break;
9129 }
9130 case 0xDA:
9131 {
9132 std::uint32_t subtype_to_ignore{};
9133 get_number(input_format_t::cbor, subtype_to_ignore);
9134 break;
9135 }
9136 case 0xDB:
9137 {
9138 std::uint64_t subtype_to_ignore{};
9139 get_number(input_format_t::cbor, subtype_to_ignore);
9140 break;
9141 }
9142 default:
9143 break;
9144 }
9145 return parse_cbor_internal(true, tag_handler);
9146 }
9147
9149 {
9150 binary_t b;
9151 // use binary subtype and store in binary container
9152 switch (current)
9153 {
9154 case 0xD8:
9155 {
9156 std::uint8_t subtype{};
9158 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9159 break;
9160 }
9161 case 0xD9:
9162 {
9163 std::uint16_t subtype{};
9165 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9166 break;
9167 }
9168 case 0xDA:
9169 {
9170 std::uint32_t subtype{};
9172 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9173 break;
9174 }
9175 case 0xDB:
9176 {
9177 std::uint64_t subtype{};
9179 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9180 break;
9181 }
9182 default:
9183 return parse_cbor_internal(true, tag_handler);
9184 }
9185 get();
9186 return get_cbor_binary(b) && sax->binary(b);
9187 }
9188
9189 default: // LCOV_EXCL_LINE
9190 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9191 return false; // LCOV_EXCL_LINE
9192 }
9193 }
9194
9195 case 0xF4: // false
9196 return sax->boolean(false);
9197
9198 case 0xF5: // true
9199 return sax->boolean(true);
9200
9201 case 0xF6: // null
9202 return sax->null();
9203
9204 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9205 {
9206 const auto byte1_raw = get();
9208 {
9209 return false;
9210 }
9211 const auto byte2_raw = get();
9213 {
9214 return false;
9215 }
9216
9217 const auto byte1 = static_cast<unsigned char>(byte1_raw);
9218 const auto byte2 = static_cast<unsigned char>(byte2_raw);
9219
9220 // code from RFC 7049, Appendix D, Figure 3:
9221 // As half-precision floating-point numbers were only added
9222 // to IEEE 754 in 2008, today's programming platforms often
9223 // still only have limited support for them. It is very
9224 // easy to include at least decoding support for them even
9225 // without such support. An example of a small decoder for
9226 // half-precision floating-point numbers in the C language
9227 // is shown in Fig. 3.
9228 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9229 const double val = [&half]
9230 {
9231 const int exp = (half >> 10u) & 0x1Fu;
9232 const unsigned int mant = half & 0x3FFu;
9233 JSON_ASSERT(0 <= exp&& exp <= 32);
9234 JSON_ASSERT(mant <= 1024);
9235 switch (exp)
9236 {
9237 case 0:
9238 return std::ldexp(mant, -24);
9239 case 31:
9240 return (mant == 0)
9241 ? std::numeric_limits<double>::infinity()
9242 : std::numeric_limits<double>::quiet_NaN();
9243 default:
9244 return std::ldexp(mant + 1024, exp - 25);
9245 }
9246 }();
9247 return sax->number_float((half & 0x8000u) != 0
9248 ? static_cast<number_float_t>(-val)
9249 : static_cast<number_float_t>(val), "");
9250 }
9251
9252 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9253 {
9254 float number{};
9255 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9256 }
9257
9258 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9259 {
9260 double number{};
9261 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9262 }
9263
9264 default: // anything else (0xFF is handled inside the other types)
9265 {
9266 auto last_token = get_token_string();
9267 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9268 }
9269 }
9270 }
9271
9284 {
9286 {
9287 return false;
9288 }
9289
9290 switch (current)
9291 {
9292 // UTF-8 string (0x00..0x17 bytes follow)
9293 case 0x60:
9294 case 0x61:
9295 case 0x62:
9296 case 0x63:
9297 case 0x64:
9298 case 0x65:
9299 case 0x66:
9300 case 0x67:
9301 case 0x68:
9302 case 0x69:
9303 case 0x6A:
9304 case 0x6B:
9305 case 0x6C:
9306 case 0x6D:
9307 case 0x6E:
9308 case 0x6F:
9309 case 0x70:
9310 case 0x71:
9311 case 0x72:
9312 case 0x73:
9313 case 0x74:
9314 case 0x75:
9315 case 0x76:
9316 case 0x77:
9317 {
9318 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9319 }
9320
9321 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9322 {
9323 std::uint8_t len{};
9324 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9325 }
9326
9327 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9328 {
9329 std::uint16_t len{};
9330 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9331 }
9332
9333 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9334 {
9335 std::uint32_t len{};
9336 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9337 }
9338
9339 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9340 {
9341 std::uint64_t len{};
9342 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9343 }
9344
9345 case 0x7F: // UTF-8 string (indefinite length)
9346 {
9347 while (get() != 0xFF)
9348 {
9349 string_t chunk;
9350 if (!get_cbor_string(chunk))
9351 {
9352 return false;
9353 }
9354 result.append(chunk);
9355 }
9356 return true;
9357 }
9358
9359 default:
9360 {
9361 auto last_token = get_token_string();
9362 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string"), BasicJsonType()));
9363 }
9364 }
9365 }
9366
9379 {
9381 {
9382 return false;
9383 }
9384
9385 switch (current)
9386 {
9387 // Binary data (0x00..0x17 bytes follow)
9388 case 0x40:
9389 case 0x41:
9390 case 0x42:
9391 case 0x43:
9392 case 0x44:
9393 case 0x45:
9394 case 0x46:
9395 case 0x47:
9396 case 0x48:
9397 case 0x49:
9398 case 0x4A:
9399 case 0x4B:
9400 case 0x4C:
9401 case 0x4D:
9402 case 0x4E:
9403 case 0x4F:
9404 case 0x50:
9405 case 0x51:
9406 case 0x52:
9407 case 0x53:
9408 case 0x54:
9409 case 0x55:
9410 case 0x56:
9411 case 0x57:
9412 {
9413 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9414 }
9415
9416 case 0x58: // Binary data (one-byte uint8_t for n follows)
9417 {
9418 std::uint8_t len{};
9419 return get_number(input_format_t::cbor, len) &&
9420 get_binary(input_format_t::cbor, len, result);
9421 }
9422
9423 case 0x59: // Binary data (two-byte uint16_t for n follow)
9424 {
9425 std::uint16_t len{};
9426 return get_number(input_format_t::cbor, len) &&
9427 get_binary(input_format_t::cbor, len, result);
9428 }
9429
9430 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9431 {
9432 std::uint32_t len{};
9433 return get_number(input_format_t::cbor, len) &&
9434 get_binary(input_format_t::cbor, len, result);
9435 }
9436
9437 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9438 {
9439 std::uint64_t len{};
9440 return get_number(input_format_t::cbor, len) &&
9441 get_binary(input_format_t::cbor, len, result);
9442 }
9443
9444 case 0x5F: // Binary data (indefinite length)
9445 {
9446 while (get() != 0xFF)
9447 {
9448 binary_t chunk;
9449 if (!get_cbor_binary(chunk))
9450 {
9451 return false;
9452 }
9453 result.insert(result.end(), chunk.begin(), chunk.end());
9454 }
9455 return true;
9456 }
9457
9458 default:
9459 {
9460 auto last_token = get_token_string();
9461 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary"), BasicJsonType()));
9462 }
9463 }
9464 }
9465
9472 bool get_cbor_array(const std::size_t len,
9473 const cbor_tag_handler_t tag_handler)
9474 {
9475 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9476 {
9477 return false;
9478 }
9479
9480 if (len != std::size_t(-1))
9481 {
9482 for (std::size_t i = 0; i < len; ++i)
9483 {
9484 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9485 {
9486 return false;
9487 }
9488 }
9489 }
9490 else
9491 {
9492 while (get() != 0xFF)
9493 {
9494 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9495 {
9496 return false;
9497 }
9498 }
9499 }
9500
9501 return sax->end_array();
9502 }
9503
9510 bool get_cbor_object(const std::size_t len,
9511 const cbor_tag_handler_t tag_handler)
9512 {
9513 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9514 {
9515 return false;
9516 }
9517
9518 if (len != 0)
9519 {
9520 string_t key;
9521 if (len != std::size_t(-1))
9522 {
9523 for (std::size_t i = 0; i < len; ++i)
9524 {
9525 get();
9527 {
9528 return false;
9529 }
9530
9531 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9532 {
9533 return false;
9534 }
9535 key.clear();
9536 }
9537 }
9538 else
9539 {
9540 while (get() != 0xFF)
9541 {
9543 {
9544 return false;
9545 }
9546
9547 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9548 {
9549 return false;
9550 }
9551 key.clear();
9552 }
9553 }
9554 }
9555
9556 return sax->end_object();
9557 }
9558
9560 // MsgPack //
9562
9567 {
9568 switch (get())
9569 {
9570 // EOF
9571 case std::char_traits<char_type>::eof():
9572 return unexpect_eof(input_format_t::msgpack, "value");
9573
9574 // positive fixint
9575 case 0x00:
9576 case 0x01:
9577 case 0x02:
9578 case 0x03:
9579 case 0x04:
9580 case 0x05:
9581 case 0x06:
9582 case 0x07:
9583 case 0x08:
9584 case 0x09:
9585 case 0x0A:
9586 case 0x0B:
9587 case 0x0C:
9588 case 0x0D:
9589 case 0x0E:
9590 case 0x0F:
9591 case 0x10:
9592 case 0x11:
9593 case 0x12:
9594 case 0x13:
9595 case 0x14:
9596 case 0x15:
9597 case 0x16:
9598 case 0x17:
9599 case 0x18:
9600 case 0x19:
9601 case 0x1A:
9602 case 0x1B:
9603 case 0x1C:
9604 case 0x1D:
9605 case 0x1E:
9606 case 0x1F:
9607 case 0x20:
9608 case 0x21:
9609 case 0x22:
9610 case 0x23:
9611 case 0x24:
9612 case 0x25:
9613 case 0x26:
9614 case 0x27:
9615 case 0x28:
9616 case 0x29:
9617 case 0x2A:
9618 case 0x2B:
9619 case 0x2C:
9620 case 0x2D:
9621 case 0x2E:
9622 case 0x2F:
9623 case 0x30:
9624 case 0x31:
9625 case 0x32:
9626 case 0x33:
9627 case 0x34:
9628 case 0x35:
9629 case 0x36:
9630 case 0x37:
9631 case 0x38:
9632 case 0x39:
9633 case 0x3A:
9634 case 0x3B:
9635 case 0x3C:
9636 case 0x3D:
9637 case 0x3E:
9638 case 0x3F:
9639 case 0x40:
9640 case 0x41:
9641 case 0x42:
9642 case 0x43:
9643 case 0x44:
9644 case 0x45:
9645 case 0x46:
9646 case 0x47:
9647 case 0x48:
9648 case 0x49:
9649 case 0x4A:
9650 case 0x4B:
9651 case 0x4C:
9652 case 0x4D:
9653 case 0x4E:
9654 case 0x4F:
9655 case 0x50:
9656 case 0x51:
9657 case 0x52:
9658 case 0x53:
9659 case 0x54:
9660 case 0x55:
9661 case 0x56:
9662 case 0x57:
9663 case 0x58:
9664 case 0x59:
9665 case 0x5A:
9666 case 0x5B:
9667 case 0x5C:
9668 case 0x5D:
9669 case 0x5E:
9670 case 0x5F:
9671 case 0x60:
9672 case 0x61:
9673 case 0x62:
9674 case 0x63:
9675 case 0x64:
9676 case 0x65:
9677 case 0x66:
9678 case 0x67:
9679 case 0x68:
9680 case 0x69:
9681 case 0x6A:
9682 case 0x6B:
9683 case 0x6C:
9684 case 0x6D:
9685 case 0x6E:
9686 case 0x6F:
9687 case 0x70:
9688 case 0x71:
9689 case 0x72:
9690 case 0x73:
9691 case 0x74:
9692 case 0x75:
9693 case 0x76:
9694 case 0x77:
9695 case 0x78:
9696 case 0x79:
9697 case 0x7A:
9698 case 0x7B:
9699 case 0x7C:
9700 case 0x7D:
9701 case 0x7E:
9702 case 0x7F:
9703 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9704
9705 // fixmap
9706 case 0x80:
9707 case 0x81:
9708 case 0x82:
9709 case 0x83:
9710 case 0x84:
9711 case 0x85:
9712 case 0x86:
9713 case 0x87:
9714 case 0x88:
9715 case 0x89:
9716 case 0x8A:
9717 case 0x8B:
9718 case 0x8C:
9719 case 0x8D:
9720 case 0x8E:
9721 case 0x8F:
9722 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9723
9724 // fixarray
9725 case 0x90:
9726 case 0x91:
9727 case 0x92:
9728 case 0x93:
9729 case 0x94:
9730 case 0x95:
9731 case 0x96:
9732 case 0x97:
9733 case 0x98:
9734 case 0x99:
9735 case 0x9A:
9736 case 0x9B:
9737 case 0x9C:
9738 case 0x9D:
9739 case 0x9E:
9740 case 0x9F:
9741 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9742
9743 // fixstr
9744 case 0xA0:
9745 case 0xA1:
9746 case 0xA2:
9747 case 0xA3:
9748 case 0xA4:
9749 case 0xA5:
9750 case 0xA6:
9751 case 0xA7:
9752 case 0xA8:
9753 case 0xA9:
9754 case 0xAA:
9755 case 0xAB:
9756 case 0xAC:
9757 case 0xAD:
9758 case 0xAE:
9759 case 0xAF:
9760 case 0xB0:
9761 case 0xB1:
9762 case 0xB2:
9763 case 0xB3:
9764 case 0xB4:
9765 case 0xB5:
9766 case 0xB6:
9767 case 0xB7:
9768 case 0xB8:
9769 case 0xB9:
9770 case 0xBA:
9771 case 0xBB:
9772 case 0xBC:
9773 case 0xBD:
9774 case 0xBE:
9775 case 0xBF:
9776 case 0xD9: // str 8
9777 case 0xDA: // str 16
9778 case 0xDB: // str 32
9779 {
9780 string_t s;
9781 return get_msgpack_string(s) && sax->string(s);
9782 }
9783
9784 case 0xC0: // nil
9785 return sax->null();
9786
9787 case 0xC2: // false
9788 return sax->boolean(false);
9789
9790 case 0xC3: // true
9791 return sax->boolean(true);
9792
9793 case 0xC4: // bin 8
9794 case 0xC5: // bin 16
9795 case 0xC6: // bin 32
9796 case 0xC7: // ext 8
9797 case 0xC8: // ext 16
9798 case 0xC9: // ext 32
9799 case 0xD4: // fixext 1
9800 case 0xD5: // fixext 2
9801 case 0xD6: // fixext 4
9802 case 0xD7: // fixext 8
9803 case 0xD8: // fixext 16
9804 {
9805 binary_t b;
9806 return get_msgpack_binary(b) && sax->binary(b);
9807 }
9808
9809 case 0xCA: // float 32
9810 {
9811 float number{};
9812 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9813 }
9814
9815 case 0xCB: // float 64
9816 {
9817 double number{};
9818 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9819 }
9820
9821 case 0xCC: // uint 8
9822 {
9823 std::uint8_t number{};
9824 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9825 }
9826
9827 case 0xCD: // uint 16
9828 {
9829 std::uint16_t number{};
9830 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9831 }
9832
9833 case 0xCE: // uint 32
9834 {
9835 std::uint32_t number{};
9836 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9837 }
9838
9839 case 0xCF: // uint 64
9840 {
9841 std::uint64_t number{};
9842 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9843 }
9844
9845 case 0xD0: // int 8
9846 {
9847 std::int8_t number{};
9848 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9849 }
9850
9851 case 0xD1: // int 16
9852 {
9853 std::int16_t number{};
9854 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9855 }
9856
9857 case 0xD2: // int 32
9858 {
9859 std::int32_t number{};
9860 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9861 }
9862
9863 case 0xD3: // int 64
9864 {
9865 std::int64_t number{};
9866 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9867 }
9868
9869 case 0xDC: // array 16
9870 {
9871 std::uint16_t len{};
9872 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9873 }
9874
9875 case 0xDD: // array 32
9876 {
9877 std::uint32_t len{};
9878 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9879 }
9880
9881 case 0xDE: // map 16
9882 {
9883 std::uint16_t len{};
9884 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9885 }
9886
9887 case 0xDF: // map 32
9888 {
9889 std::uint32_t len{};
9890 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9891 }
9892
9893 // negative fixint
9894 case 0xE0:
9895 case 0xE1:
9896 case 0xE2:
9897 case 0xE3:
9898 case 0xE4:
9899 case 0xE5:
9900 case 0xE6:
9901 case 0xE7:
9902 case 0xE8:
9903 case 0xE9:
9904 case 0xEA:
9905 case 0xEB:
9906 case 0xEC:
9907 case 0xED:
9908 case 0xEE:
9909 case 0xEF:
9910 case 0xF0:
9911 case 0xF1:
9912 case 0xF2:
9913 case 0xF3:
9914 case 0xF4:
9915 case 0xF5:
9916 case 0xF6:
9917 case 0xF7:
9918 case 0xF8:
9919 case 0xF9:
9920 case 0xFA:
9921 case 0xFB:
9922 case 0xFC:
9923 case 0xFD:
9924 case 0xFE:
9925 case 0xFF:
9926 return sax->number_integer(static_cast<std::int8_t>(current));
9927
9928 default: // anything else
9929 {
9930 auto last_token = get_token_string();
9931 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9932 }
9933 }
9934 }
9935
9947 {
9949 {
9950 return false;
9951 }
9952
9953 switch (current)
9954 {
9955 // fixstr
9956 case 0xA0:
9957 case 0xA1:
9958 case 0xA2:
9959 case 0xA3:
9960 case 0xA4:
9961 case 0xA5:
9962 case 0xA6:
9963 case 0xA7:
9964 case 0xA8:
9965 case 0xA9:
9966 case 0xAA:
9967 case 0xAB:
9968 case 0xAC:
9969 case 0xAD:
9970 case 0xAE:
9971 case 0xAF:
9972 case 0xB0:
9973 case 0xB1:
9974 case 0xB2:
9975 case 0xB3:
9976 case 0xB4:
9977 case 0xB5:
9978 case 0xB6:
9979 case 0xB7:
9980 case 0xB8:
9981 case 0xB9:
9982 case 0xBA:
9983 case 0xBB:
9984 case 0xBC:
9985 case 0xBD:
9986 case 0xBE:
9987 case 0xBF:
9988 {
9989 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9990 }
9991
9992 case 0xD9: // str 8
9993 {
9994 std::uint8_t len{};
9996 }
9997
9998 case 0xDA: // str 16
9999 {
10000 std::uint16_t len{};
10002 }
10003
10004 case 0xDB: // str 32
10005 {
10006 std::uint32_t len{};
10008 }
10009
10010 default:
10011 {
10012 auto last_token = get_token_string();
10013 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string"), BasicJsonType()));
10014 }
10015 }
10016 }
10017
10029 {
10030 // helper function to set the subtype
10031 auto assign_and_return_true = [&result](std::int8_t subtype)
10032 {
10033 result.set_subtype(static_cast<std::uint8_t>(subtype));
10034 return true;
10035 };
10036
10037 switch (current)
10038 {
10039 case 0xC4: // bin 8
10040 {
10041 std::uint8_t len{};
10042 return get_number(input_format_t::msgpack, len) &&
10043 get_binary(input_format_t::msgpack, len, result);
10044 }
10045
10046 case 0xC5: // bin 16
10047 {
10048 std::uint16_t len{};
10049 return get_number(input_format_t::msgpack, len) &&
10050 get_binary(input_format_t::msgpack, len, result);
10051 }
10052
10053 case 0xC6: // bin 32
10054 {
10055 std::uint32_t len{};
10056 return get_number(input_format_t::msgpack, len) &&
10057 get_binary(input_format_t::msgpack, len, result);
10058 }
10059
10060 case 0xC7: // ext 8
10061 {
10062 std::uint8_t len{};
10063 std::int8_t subtype{};
10064 return get_number(input_format_t::msgpack, len) &&
10066 get_binary(input_format_t::msgpack, len, result) &&
10067 assign_and_return_true(subtype);
10068 }
10069
10070 case 0xC8: // ext 16
10071 {
10072 std::uint16_t len{};
10073 std::int8_t subtype{};
10074 return get_number(input_format_t::msgpack, len) &&
10076 get_binary(input_format_t::msgpack, len, result) &&
10077 assign_and_return_true(subtype);
10078 }
10079
10080 case 0xC9: // ext 32
10081 {
10082 std::uint32_t len{};
10083 std::int8_t subtype{};
10084 return get_number(input_format_t::msgpack, len) &&
10086 get_binary(input_format_t::msgpack, len, result) &&
10087 assign_and_return_true(subtype);
10088 }
10089
10090 case 0xD4: // fixext 1
10091 {
10092 std::int8_t subtype{};
10093 return get_number(input_format_t::msgpack, subtype) &&
10094 get_binary(input_format_t::msgpack, 1, result) &&
10095 assign_and_return_true(subtype);
10096 }
10097
10098 case 0xD5: // fixext 2
10099 {
10100 std::int8_t subtype{};
10101 return get_number(input_format_t::msgpack, subtype) &&
10102 get_binary(input_format_t::msgpack, 2, result) &&
10103 assign_and_return_true(subtype);
10104 }
10105
10106 case 0xD6: // fixext 4
10107 {
10108 std::int8_t subtype{};
10109 return get_number(input_format_t::msgpack, subtype) &&
10110 get_binary(input_format_t::msgpack, 4, result) &&
10111 assign_and_return_true(subtype);
10112 }
10113
10114 case 0xD7: // fixext 8
10115 {
10116 std::int8_t subtype{};
10117 return get_number(input_format_t::msgpack, subtype) &&
10118 get_binary(input_format_t::msgpack, 8, result) &&
10119 assign_and_return_true(subtype);
10120 }
10121
10122 case 0xD8: // fixext 16
10123 {
10124 std::int8_t subtype{};
10125 return get_number(input_format_t::msgpack, subtype) &&
10126 get_binary(input_format_t::msgpack, 16, result) &&
10127 assign_and_return_true(subtype);
10128 }
10129
10130 default: // LCOV_EXCL_LINE
10131 return false; // LCOV_EXCL_LINE
10132 }
10133 }
10134
10139 bool get_msgpack_array(const std::size_t len)
10140 {
10141 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10142 {
10143 return false;
10144 }
10145
10146 for (std::size_t i = 0; i < len; ++i)
10147 {
10149 {
10150 return false;
10151 }
10152 }
10153
10154 return sax->end_array();
10155 }
10156
10161 bool get_msgpack_object(const std::size_t len)
10162 {
10163 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10164 {
10165 return false;
10166 }
10167
10168 string_t key;
10169 for (std::size_t i = 0; i < len; ++i)
10170 {
10171 get();
10173 {
10174 return false;
10175 }
10176
10178 {
10179 return false;
10180 }
10181 key.clear();
10182 }
10183
10184 return sax->end_object();
10185 }
10186
10188 // UBJSON //
10190
10198 bool parse_ubjson_internal(const bool get_char = true)
10199 {
10200 return get_ubjson_value(get_char ? get_ignore_noop() : current);
10201 }
10202
10217 bool get_ubjson_string(string_t& result, const bool get_char = true)
10218 {
10219 if (get_char)
10220 {
10221 get(); // TODO(niels): may we ignore N here?
10222 }
10223
10225 {
10226 return false;
10227 }
10228
10229 switch (current)
10230 {
10231 case 'U':
10232 {
10233 std::uint8_t len{};
10235 }
10236
10237 case 'i':
10238 {
10239 std::int8_t len{};
10241 }
10242
10243 case 'I':
10244 {
10245 std::int16_t len{};
10247 }
10248
10249 case 'l':
10250 {
10251 std::int32_t len{};
10253 }
10254
10255 case 'L':
10256 {
10257 std::int64_t len{};
10259 }
10260
10261 default:
10262 auto last_token = get_token_string();
10263 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"), BasicJsonType()));
10264 }
10265 }
10266
10271 bool get_ubjson_size_value(std::size_t& result)
10272 {
10273 switch (get_ignore_noop())
10274 {
10275 case 'U':
10276 {
10277 std::uint8_t number{};
10279 {
10280 return false;
10281 }
10282 result = static_cast<std::size_t>(number);
10283 return true;
10284 }
10285
10286 case 'i':
10287 {
10288 std::int8_t number{};
10290 {
10291 return false;
10292 }
10293 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10294 return true;
10295 }
10296
10297 case 'I':
10298 {
10299 std::int16_t number{};
10301 {
10302 return false;
10303 }
10304 result = static_cast<std::size_t>(number);
10305 return true;
10306 }
10307
10308 case 'l':
10309 {
10310 std::int32_t number{};
10312 {
10313 return false;
10314 }
10315 result = static_cast<std::size_t>(number);
10316 return true;
10317 }
10318
10319 case 'L':
10320 {
10321 std::int64_t number{};
10323 {
10324 return false;
10325 }
10326 result = static_cast<std::size_t>(number);
10327 return true;
10328 }
10329
10330 default:
10331 {
10332 auto last_token = get_token_string();
10333 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"), BasicJsonType()));
10334 }
10335 }
10336 }
10337
10348 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
10349 {
10350 result.first = string_t::npos; // size
10351 result.second = 0; // type
10352
10354
10355 if (current == '$')
10356 {
10357 result.second = get(); // must not ignore 'N', because 'N' maybe the type
10359 {
10360 return false;
10361 }
10362
10364 if (JSON_HEDLEY_UNLIKELY(current != '#'))
10365 {
10367 {
10368 return false;
10369 }
10370 auto last_token = get_token_string();
10371 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size"), BasicJsonType()));
10372 }
10373
10374 return get_ubjson_size_value(result.first);
10375 }
10376
10377 if (current == '#')
10378 {
10379 return get_ubjson_size_value(result.first);
10380 }
10381
10382 return true;
10383 }
10384
10390 {
10391 switch (prefix)
10392 {
10393 case std::char_traits<char_type>::eof(): // EOF
10394 return unexpect_eof(input_format_t::ubjson, "value");
10395
10396 case 'T': // true
10397 return sax->boolean(true);
10398 case 'F': // false
10399 return sax->boolean(false);
10400
10401 case 'Z': // null
10402 return sax->null();
10403
10404 case 'U':
10405 {
10406 std::uint8_t number{};
10407 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
10408 }
10409
10410 case 'i':
10411 {
10412 std::int8_t number{};
10413 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10414 }
10415
10416 case 'I':
10417 {
10418 std::int16_t number{};
10419 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10420 }
10421
10422 case 'l':
10423 {
10424 std::int32_t number{};
10425 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10426 }
10427
10428 case 'L':
10429 {
10430 std::int64_t number{};
10431 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10432 }
10433
10434 case 'd':
10435 {
10436 float number{};
10437 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10438 }
10439
10440 case 'D':
10441 {
10442 double number{};
10443 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10444 }
10445
10446 case 'H':
10447 {
10449 }
10450
10451 case 'C': // char
10452 {
10453 get();
10455 {
10456 return false;
10457 }
10458 if (JSON_HEDLEY_UNLIKELY(current > 127))
10459 {
10460 auto last_token = get_token_string();
10461 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char"), BasicJsonType()));
10462 }
10463 string_t s(1, static_cast<typename string_t::value_type>(current));
10464 return sax->string(s);
10465 }
10466
10467 case 'S': // string
10468 {
10469 string_t s;
10470 return get_ubjson_string(s) && sax->string(s);
10471 }
10472
10473 case '[': // array
10474 return get_ubjson_array();
10475
10476 case '{': // object
10477 return get_ubjson_object();
10478
10479 default: // anything else
10480 {
10481 auto last_token = get_token_string();
10482 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
10483 }
10484 }
10485 }
10486
10491 {
10492 std::pair<std::size_t, char_int_type> size_and_type;
10493 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10494 {
10495 return false;
10496 }
10497
10498 if (size_and_type.first != string_t::npos)
10499 {
10500 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
10501 {
10502 return false;
10503 }
10504
10505 if (size_and_type.second != 0)
10506 {
10507 if (size_and_type.second != 'N')
10508 {
10509 for (std::size_t i = 0; i < size_and_type.first; ++i)
10510 {
10511 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10512 {
10513 return false;
10514 }
10515 }
10516 }
10517 }
10518 else
10519 {
10520 for (std::size_t i = 0; i < size_and_type.first; ++i)
10521 {
10523 {
10524 return false;
10525 }
10526 }
10527 }
10528 }
10529 else
10530 {
10531 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10532 {
10533 return false;
10534 }
10535
10536 while (current != ']')
10537 {
10539 {
10540 return false;
10541 }
10543 }
10544 }
10545
10546 return sax->end_array();
10547 }
10548
10553 {
10554 std::pair<std::size_t, char_int_type> size_and_type;
10555 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10556 {
10557 return false;
10558 }
10559
10560 string_t key;
10561 if (size_and_type.first != string_t::npos)
10562 {
10563 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
10564 {
10565 return false;
10566 }
10567
10568 if (size_and_type.second != 0)
10569 {
10570 for (std::size_t i = 0; i < size_and_type.first; ++i)
10571 {
10573 {
10574 return false;
10575 }
10576 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10577 {
10578 return false;
10579 }
10580 key.clear();
10581 }
10582 }
10583 else
10584 {
10585 for (std::size_t i = 0; i < size_and_type.first; ++i)
10586 {
10588 {
10589 return false;
10590 }
10592 {
10593 return false;
10594 }
10595 key.clear();
10596 }
10597 }
10598 }
10599 else
10600 {
10601 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10602 {
10603 return false;
10604 }
10605
10606 while (current != '}')
10607 {
10608 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
10609 {
10610 return false;
10611 }
10613 {
10614 return false;
10615 }
10617 key.clear();
10618 }
10619 }
10620
10621 return sax->end_object();
10622 }
10623
10624 // Note, no reader for UBJSON binary types is implemented because they do
10625 // not exist
10626
10628 {
10629 // get size of following number string
10630 std::size_t size{};
10631 auto res = get_ubjson_size_value(size);
10632 if (JSON_HEDLEY_UNLIKELY(!res))
10633 {
10634 return res;
10635 }
10636
10637 // get number string
10638 std::vector<char> number_vector;
10639 for (std::size_t i = 0; i < size; ++i)
10640 {
10641 get();
10643 {
10644 return false;
10645 }
10646 number_vector.push_back(static_cast<char>(current));
10647 }
10648
10649 // parse number string
10650 using ia_type = decltype(detail::input_adapter(number_vector));
10651 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
10652 const auto result_number = number_lexer.scan();
10653 const auto number_string = number_lexer.get_token_string();
10654 const auto result_remainder = number_lexer.scan();
10655
10656 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
10657
10658 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
10659 {
10660 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
10661 }
10662
10663 switch (result_number)
10664 {
10665 case token_type::value_integer:
10666 return sax->number_integer(number_lexer.get_number_integer());
10667 case token_type::value_unsigned:
10668 return sax->number_unsigned(number_lexer.get_number_unsigned());
10669 case token_type::value_float:
10670 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
10671 case token_type::uninitialized:
10672 case token_type::literal_true:
10673 case token_type::literal_false:
10674 case token_type::literal_null:
10675 case token_type::value_string:
10676 case token_type::begin_array:
10677 case token_type::begin_object:
10678 case token_type::end_array:
10679 case token_type::end_object:
10680 case token_type::name_separator:
10681 case token_type::value_separator:
10682 case token_type::parse_error:
10683 case token_type::end_of_input:
10684 case token_type::literal_or_value:
10685 default:
10686 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
10687 }
10688 }
10689
10691 // Utility functions //
10693
10704 {
10705 ++chars_read;
10706 return current = ia.get_character();
10707 }
10708
10713 {
10714 do
10715 {
10716 get();
10717 }
10718 while (current == 'N');
10719
10720 return current;
10721 }
10722
10723 /*
10724 @brief read a number from the input
10725
10726 @tparam NumberType the type of the number
10727 @param[in] format the current format (for diagnostics)
10728 @param[out] result number of type @a NumberType
10729
10730 @return whether conversion completed
10731
10732 @note This function needs to respect the system's endianness, because
10733 bytes in CBOR, MessagePack, and UBJSON are stored in network order
10734 (big endian) and therefore need reordering on little endian systems.
10735 */
10736 template<typename NumberType, bool InputIsLittleEndian = false>
10737 bool get_number(const input_format_t format, NumberType& result)
10738 {
10739 // step 1: read input into array with system's byte order
10740 std::array<std::uint8_t, sizeof(NumberType)> vec{};
10741 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
10742 {
10743 get();
10744 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10745 {
10746 return false;
10747 }
10748
10749 // reverse byte order prior to conversion if necessary
10750 if (is_little_endian != InputIsLittleEndian)
10751 {
10752 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10753 }
10754 else
10755 {
10756 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10757 }
10758 }
10759
10760 // step 2: convert array into number of type T and return
10761 std::memcpy(&result, vec.data(), sizeof(NumberType));
10762 return true;
10763 }
10764
10779 template<typename NumberType>
10780 bool get_string(const input_format_t format,
10781 const NumberType len,
10782 string_t& result)
10783 {
10784 bool success = true;
10785 for (NumberType i = 0; i < len; i++)
10786 {
10787 get();
10788 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10789 {
10790 success = false;
10791 break;
10792 }
10793 result.push_back(static_cast<typename string_t::value_type>(current));
10794 }
10795 return success;
10796 }
10797
10812 template<typename NumberType>
10813 bool get_binary(const input_format_t format,
10814 const NumberType len,
10815 binary_t& result)
10816 {
10817 bool success = true;
10818 for (NumberType i = 0; i < len; i++)
10819 {
10820 get();
10821 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10822 {
10823 success = false;
10824 break;
10825 }
10826 result.push_back(static_cast<std::uint8_t>(current));
10827 }
10828 return success;
10829 }
10830
10837 bool unexpect_eof(const input_format_t format, const char* context) const
10838 {
10839 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10840 {
10841 return sax->parse_error(chars_read, "<end of file>",
10842 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
10843 }
10844 return true;
10845 }
10846
10850 std::string get_token_string() const
10851 {
10852 std::array<char, 3> cr{{}};
10853 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10854 return std::string{cr.data()};
10855 }
10856
10863 std::string exception_message(const input_format_t format,
10864 const std::string& detail,
10865 const std::string& context) const
10866 {
10867 std::string error_msg = "syntax error while parsing ";
10868
10869 switch (format)
10870 {
10872 error_msg += "CBOR";
10873 break;
10874
10876 error_msg += "MessagePack";
10877 break;
10878
10880 error_msg += "UBJSON";
10881 break;
10882
10884 error_msg += "BSON";
10885 break;
10886
10887 case input_format_t::json: // LCOV_EXCL_LINE
10888 default: // LCOV_EXCL_LINE
10889 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10890 }
10891
10892 return error_msg + " " + context + ": " + detail;
10893 }
10894
10895 private:
10897 InputAdapterType ia;
10898
10900 char_int_type current = std::char_traits<char_type>::eof();
10901
10903 std::size_t chars_read = 0;
10904
10907
10909 json_sax_t* sax = nullptr;
10910};
10911} // namespace detail
10912} // namespace nlohmann
10913
10914// #include <nlohmann/detail/input/input_adapters.hpp>
10915
10916// #include <nlohmann/detail/input/lexer.hpp>
10917
10918// #include <nlohmann/detail/input/parser.hpp>
10919
10920
10921#include <cmath> // isfinite
10922#include <cstdint> // uint8_t
10923#include <functional> // function
10924#include <string> // string
10925#include <utility> // move
10926#include <vector> // vector
10927
10928// #include <nlohmann/detail/exceptions.hpp>
10929
10930// #include <nlohmann/detail/input/input_adapters.hpp>
10931
10932// #include <nlohmann/detail/input/json_sax.hpp>
10933
10934// #include <nlohmann/detail/input/lexer.hpp>
10935
10936// #include <nlohmann/detail/macro_scope.hpp>
10937
10938// #include <nlohmann/detail/meta/is_sax.hpp>
10939
10940// #include <nlohmann/detail/value_t.hpp>
10941
10942
10943namespace nlohmann
10944{
10945namespace detail
10946{
10948// parser //
10950
10951enum class parse_event_t : std::uint8_t
10952{
10956 object_end,
10960 array_end,
10962 key,
10964 value
10965};
10966
10967template<typename BasicJsonType>
10969 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
10970
10976template<typename BasicJsonType, typename InputAdapterType>
10978{
10979 using number_integer_t = typename BasicJsonType::number_integer_t;
10980 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10981 using number_float_t = typename BasicJsonType::number_float_t;
10982 using string_t = typename BasicJsonType::string_t;
10985
10986 public:
10988 explicit parser(InputAdapterType&& adapter,
10989 const parser_callback_t<BasicJsonType> cb = nullptr,
10990 const bool allow_exceptions_ = true,
10991 const bool skip_comments = false)
10992 : callback(cb)
10993 , m_lexer(std::move(adapter), skip_comments)
10994 , allow_exceptions(allow_exceptions_)
10995 {
10996 // read first token
10997 get_token();
10998 }
10999
11010 void parse(const bool strict, BasicJsonType& result)
11011 {
11012 if (callback)
11013 {
11015 sax_parse_internal(&sdp);
11016
11017 // in strict mode, input must be completely read
11018 if (strict && (get_token() != token_type::end_of_input))
11019 {
11023 exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11024 }
11025
11026 // in case of an error, return discarded value
11027 if (sdp.is_errored())
11028 {
11029 result = value_t::discarded;
11030 return;
11031 }
11032
11033 // set top-level value to null if it was discarded by the callback
11034 // function
11035 if (result.is_discarded())
11036 {
11037 result = nullptr;
11038 }
11039 }
11040 else
11041 {
11043 sax_parse_internal(&sdp);
11044
11045 // in strict mode, input must be completely read
11046 if (strict && (get_token() != token_type::end_of_input))
11047 {
11050 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11051 }
11052
11053 // in case of an error, return discarded value
11054 if (sdp.is_errored())
11055 {
11056 result = value_t::discarded;
11057 return;
11058 }
11059 }
11060
11061 result.assert_invariant();
11062 }
11063
11070 bool accept(const bool strict = true)
11071 {
11073 return sax_parse(&sax_acceptor, strict);
11074 }
11075
11076 template<typename SAX>
11078 bool sax_parse(SAX* sax, const bool strict = true)
11079 {
11081 const bool result = sax_parse_internal(sax);
11082
11083 // strict mode: next byte must be EOF
11084 if (result && strict && (get_token() != token_type::end_of_input))
11085 {
11086 return sax->parse_error(m_lexer.get_position(),
11088 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11089 }
11090
11091 return result;
11092 }
11093
11094 private:
11095 template<typename SAX>
11097 bool sax_parse_internal(SAX* sax)
11098 {
11099 // stack to remember the hierarchy of structured values we are parsing
11100 // true = array; false = object
11101 std::vector<bool> states;
11102 // value to avoid a goto (see comment where set to true)
11103 bool skip_to_state_evaluation = false;
11104
11105 while (true)
11106 {
11107 if (!skip_to_state_evaluation)
11108 {
11109 // invariant: get_token() was called before each iteration
11110 switch (last_token)
11111 {
11112 case token_type::begin_object:
11113 {
11114 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
11115 {
11116 return false;
11117 }
11118
11119 // closing } -> we are done
11120 if (get_token() == token_type::end_object)
11121 {
11122 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11123 {
11124 return false;
11125 }
11126 break;
11127 }
11128
11129 // parse key
11130 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11131 {
11132 return sax->parse_error(m_lexer.get_position(),
11134 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11135 }
11136 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11137 {
11138 return false;
11139 }
11140
11141 // parse separator (:)
11142 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11143 {
11144 return sax->parse_error(m_lexer.get_position(),
11146 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11147 }
11148
11149 // remember we are now inside an object
11150 states.push_back(false);
11151
11152 // parse values
11153 get_token();
11154 continue;
11155 }
11156
11157 case token_type::begin_array:
11158 {
11159 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
11160 {
11161 return false;
11162 }
11163
11164 // closing ] -> we are done
11165 if (get_token() == token_type::end_array)
11166 {
11167 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11168 {
11169 return false;
11170 }
11171 break;
11172 }
11173
11174 // remember we are now inside an array
11175 states.push_back(true);
11176
11177 // parse values (no need to call get_token)
11178 continue;
11179 }
11180
11181 case token_type::value_float:
11182 {
11183 const auto res = m_lexer.get_number_float();
11184
11185 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11186 {
11187 return sax->parse_error(m_lexer.get_position(),
11189 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
11190 }
11191
11192 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11193 {
11194 return false;
11195 }
11196
11197 break;
11198 }
11199
11200 case token_type::literal_false:
11201 {
11202 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11203 {
11204 return false;
11205 }
11206 break;
11207 }
11208
11209 case token_type::literal_null:
11210 {
11211 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11212 {
11213 return false;
11214 }
11215 break;
11216 }
11217
11218 case token_type::literal_true:
11219 {
11220 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11221 {
11222 return false;
11223 }
11224 break;
11225 }
11226
11227 case token_type::value_integer:
11228 {
11229 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11230 {
11231 return false;
11232 }
11233 break;
11234 }
11235
11236 case token_type::value_string:
11237 {
11238 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11239 {
11240 return false;
11241 }
11242 break;
11243 }
11244
11245 case token_type::value_unsigned:
11246 {
11247 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11248 {
11249 return false;
11250 }
11251 break;
11252 }
11253
11254 case token_type::parse_error:
11255 {
11256 // using "uninitialized" to avoid "expected" message
11257 return sax->parse_error(m_lexer.get_position(),
11259 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
11260 }
11261
11262 case token_type::uninitialized:
11263 case token_type::end_array:
11264 case token_type::end_object:
11265 case token_type::name_separator:
11266 case token_type::value_separator:
11267 case token_type::end_of_input:
11268 case token_type::literal_or_value:
11269 default: // the last token was unexpected
11270 {
11271 return sax->parse_error(m_lexer.get_position(),
11273 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
11274 }
11275 }
11276 }
11277 else
11278 {
11279 skip_to_state_evaluation = false;
11280 }
11281
11282 // we reached this line after we successfully parsed a value
11283 if (states.empty())
11284 {
11285 // empty stack: we reached the end of the hierarchy: done
11286 return true;
11287 }
11288
11289 if (states.back()) // array
11290 {
11291 // comma -> next value
11292 if (get_token() == token_type::value_separator)
11293 {
11294 // parse a new value
11295 get_token();
11296 continue;
11297 }
11298
11299 // closing ]
11300 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11301 {
11302 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11303 {
11304 return false;
11305 }
11306
11307 // We are done with this array. Before we can parse a
11308 // new value, we need to evaluate the new state first.
11309 // By setting skip_to_state_evaluation to false, we
11310 // are effectively jumping to the beginning of this if.
11311 JSON_ASSERT(!states.empty());
11312 states.pop_back();
11313 skip_to_state_evaluation = true;
11314 continue;
11315 }
11316
11317 return sax->parse_error(m_lexer.get_position(),
11319 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
11320 }
11321
11322 // states.back() is false -> object
11323
11324 // comma -> next value
11325 if (get_token() == token_type::value_separator)
11326 {
11327 // parse key
11328 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11329 {
11330 return sax->parse_error(m_lexer.get_position(),
11332 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11333 }
11334
11335 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11336 {
11337 return false;
11338 }
11339
11340 // parse separator (:)
11341 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11342 {
11343 return sax->parse_error(m_lexer.get_position(),
11345 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11346 }
11347
11348 // parse values
11349 get_token();
11350 continue;
11351 }
11352
11353 // closing }
11354 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11355 {
11356 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11357 {
11358 return false;
11359 }
11360
11361 // We are done with this object. Before we can parse a
11362 // new value, we need to evaluate the new state first.
11363 // By setting skip_to_state_evaluation to false, we
11364 // are effectively jumping to the beginning of this if.
11365 JSON_ASSERT(!states.empty());
11366 states.pop_back();
11367 skip_to_state_evaluation = true;
11368 continue;
11369 }
11370
11371 return sax->parse_error(m_lexer.get_position(),
11373 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
11374 }
11375 }
11376
11379 {
11380 return last_token = m_lexer.scan();
11381 }
11382
11383 std::string exception_message(const token_type expected, const std::string& context)
11384 {
11385 std::string error_msg = "syntax error ";
11386
11387 if (!context.empty())
11388 {
11389 error_msg += "while parsing " + context + " ";
11390 }
11391
11392 error_msg += "- ";
11393
11394 if (last_token == token_type::parse_error)
11395 {
11396 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
11397 m_lexer.get_token_string() + "'";
11398 }
11399 else
11400 {
11401 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
11402 }
11403
11404 if (expected != token_type::uninitialized)
11405 {
11406 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
11407 }
11408
11409 return error_msg;
11410 }
11411
11412 private:
11416 token_type last_token = token_type::uninitialized;
11420 const bool allow_exceptions = true;
11421};
11422
11423} // namespace detail
11424} // namespace nlohmann
11425
11426// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11427
11428
11429// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11430
11431
11432#include <cstddef> // ptrdiff_t
11433#include <limits> // numeric_limits
11434
11435// #include <nlohmann/detail/macro_scope.hpp>
11436
11437
11438namespace nlohmann
11439{
11440namespace detail
11441{
11442/*
11443@brief an iterator for primitive JSON types
11444
11445This class models an iterator for primitive JSON types (boolean, number,
11446string). It's only purpose is to allow the iterator/const_iterator classes
11447to "iterate" over primitive values. Internally, the iterator is modeled by
11448a `difference_type` variable. Value begin_value (`0`) models the begin,
11449end_value (`1`) models past the end.
11450*/
11452{
11453 private:
11454 using difference_type = std::ptrdiff_t;
11455 static constexpr difference_type begin_value = 0;
11456 static constexpr difference_type end_value = begin_value + 1;
11457
11460 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11461
11462 public:
11463 constexpr difference_type get_value() const noexcept
11464 {
11465 return m_it;
11466 }
11467
11469 void set_begin() noexcept
11470 {
11471 m_it = begin_value;
11472 }
11473
11475 void set_end() noexcept
11476 {
11477 m_it = end_value;
11478 }
11479
11481 constexpr bool is_begin() const noexcept
11482 {
11483 return m_it == begin_value;
11484 }
11485
11487 constexpr bool is_end() const noexcept
11488 {
11489 return m_it == end_value;
11490 }
11491
11492 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11493 {
11494 return lhs.m_it == rhs.m_it;
11495 }
11496
11497 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11498 {
11499 return lhs.m_it < rhs.m_it;
11500 }
11501
11503 {
11504 auto result = *this;
11505 result += n;
11506 return result;
11507 }
11508
11510 {
11511 return lhs.m_it - rhs.m_it;
11512 }
11513
11515 {
11516 ++m_it;
11517 return *this;
11518 }
11519
11520 primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
11521 {
11522 auto result = *this;
11523 ++m_it;
11524 return result;
11525 }
11526
11528 {
11529 --m_it;
11530 return *this;
11531 }
11532
11533 primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
11534 {
11535 auto result = *this;
11536 --m_it;
11537 return result;
11538 }
11539
11541 {
11542 m_it += n;
11543 return *this;
11544 }
11545
11547 {
11548 m_it -= n;
11549 return *this;
11550 }
11551};
11552} // namespace detail
11553} // namespace nlohmann
11554
11555
11556namespace nlohmann
11557{
11558namespace detail
11559{
11566template<typename BasicJsonType> struct internal_iterator
11567{
11569 typename BasicJsonType::object_t::iterator object_iterator {};
11571 typename BasicJsonType::array_t::iterator array_iterator {};
11574};
11575} // namespace detail
11576} // namespace nlohmann
11577
11578// #include <nlohmann/detail/iterators/iter_impl.hpp>
11579
11580
11581#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
11582#include <type_traits> // conditional, is_const, remove_const
11583
11584// #include <nlohmann/detail/exceptions.hpp>
11585
11586// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11587
11588// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11589
11590// #include <nlohmann/detail/macro_scope.hpp>
11591
11592// #include <nlohmann/detail/meta/cpp_future.hpp>
11593
11594// #include <nlohmann/detail/meta/type_traits.hpp>
11595
11596// #include <nlohmann/detail/value_t.hpp>
11597
11598
11599namespace nlohmann
11600{
11601namespace detail
11602{
11603// forward declare, to be able to friend it later on
11604template<typename IteratorType> class iteration_proxy;
11605template<typename IteratorType> class iteration_proxy_value;
11606
11623template<typename BasicJsonType>
11624class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
11625{
11627 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
11633
11634 using object_t = typename BasicJsonType::object_t;
11635 using array_t = typename BasicJsonType::array_t;
11636 // make sure BasicJsonType is basic_json or const basic_json
11638 "iter_impl only accepts (const) basic_json");
11639
11640 public:
11641
11647 using iterator_category = std::bidirectional_iterator_tag;
11648
11650 using value_type = typename BasicJsonType::value_type;
11652 using difference_type = typename BasicJsonType::difference_type;
11654 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
11655 typename BasicJsonType::const_pointer,
11656 typename BasicJsonType::pointer>::type;
11659 typename std::conditional<std::is_const<BasicJsonType>::value,
11660 typename BasicJsonType::const_reference,
11661 typename BasicJsonType::reference>::type;
11662
11663 iter_impl() = default;
11664 ~iter_impl() = default;
11665 iter_impl(iter_impl&&) noexcept = default;
11666 iter_impl& operator=(iter_impl&&) noexcept = default;
11667
11674 explicit iter_impl(pointer object) noexcept : m_object(object)
11675 {
11676 JSON_ASSERT(m_object != nullptr);
11677
11678 switch (m_object->m_type)
11679 {
11680 case value_t::object:
11681 {
11682 m_it.object_iterator = typename object_t::iterator();
11683 break;
11684 }
11685
11686 case value_t::array:
11687 {
11688 m_it.array_iterator = typename array_t::iterator();
11689 break;
11690 }
11691
11692 case value_t::null:
11693 case value_t::string:
11694 case value_t::boolean:
11698 case value_t::binary:
11699 case value_t::discarded:
11700 default:
11701 {
11703 break;
11704 }
11705 }
11706 }
11707
11725 : m_object(other.m_object), m_it(other.m_it)
11726 {}
11727
11735 {
11736 if (&other != this)
11737 {
11738 m_object = other.m_object;
11739 m_it = other.m_it;
11740 }
11741 return *this;
11742 }
11743
11749 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
11750 : m_object(other.m_object), m_it(other.m_it)
11751 {}
11752
11759 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
11760 {
11761 m_object = other.m_object;
11762 m_it = other.m_it;
11763 return *this;
11764 }
11765
11771 void set_begin() noexcept
11772 {
11773 JSON_ASSERT(m_object != nullptr);
11774
11775 switch (m_object->m_type)
11776 {
11777 case value_t::object:
11778 {
11779 m_it.object_iterator = m_object->m_value.object->begin();
11780 break;
11781 }
11782
11783 case value_t::array:
11784 {
11785 m_it.array_iterator = m_object->m_value.array->begin();
11786 break;
11787 }
11788
11789 case value_t::null:
11790 {
11791 // set to end so begin()==end() is true: null is empty
11793 break;
11794 }
11795
11796 case value_t::string:
11797 case value_t::boolean:
11801 case value_t::binary:
11802 case value_t::discarded:
11803 default:
11804 {
11806 break;
11807 }
11808 }
11809 }
11810
11815 void set_end() noexcept
11816 {
11817 JSON_ASSERT(m_object != nullptr);
11818
11819 switch (m_object->m_type)
11820 {
11821 case value_t::object:
11822 {
11823 m_it.object_iterator = m_object->m_value.object->end();
11824 break;
11825 }
11826
11827 case value_t::array:
11828 {
11829 m_it.array_iterator = m_object->m_value.array->end();
11830 break;
11831 }
11832
11833 case value_t::null:
11834 case value_t::string:
11835 case value_t::boolean:
11839 case value_t::binary:
11840 case value_t::discarded:
11841 default:
11842 {
11844 break;
11845 }
11846 }
11847 }
11848
11849 public:
11855 {
11856 JSON_ASSERT(m_object != nullptr);
11857
11858 switch (m_object->m_type)
11859 {
11860 case value_t::object:
11861 {
11862 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11863 return m_it.object_iterator->second;
11864 }
11865
11866 case value_t::array:
11867 {
11868 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11869 return *m_it.array_iterator;
11870 }
11871
11872 case value_t::null:
11873 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11874
11875 case value_t::string:
11876 case value_t::boolean:
11880 case value_t::binary:
11881 case value_t::discarded:
11882 default:
11883 {
11885 {
11886 return *m_object;
11887 }
11888
11889 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11890 }
11891 }
11892 }
11893
11899 {
11900 JSON_ASSERT(m_object != nullptr);
11901
11902 switch (m_object->m_type)
11903 {
11904 case value_t::object:
11905 {
11906 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11907 return &(m_it.object_iterator->second);
11908 }
11909
11910 case value_t::array:
11911 {
11912 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11913 return &*m_it.array_iterator;
11914 }
11915
11916 case value_t::null:
11917 case value_t::string:
11918 case value_t::boolean:
11922 case value_t::binary:
11923 case value_t::discarded:
11924 default:
11925 {
11927 {
11928 return m_object;
11929 }
11930
11931 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11932 }
11933 }
11934 }
11935
11940 iter_impl const operator++(int) // NOLINT(readability-const-return-type)
11941 {
11942 auto result = *this;
11943 ++(*this);
11944 return result;
11945 }
11946
11952 {
11953 JSON_ASSERT(m_object != nullptr);
11954
11955 switch (m_object->m_type)
11956 {
11957 case value_t::object:
11958 {
11959 std::advance(m_it.object_iterator, 1);
11960 break;
11961 }
11962
11963 case value_t::array:
11964 {
11965 std::advance(m_it.array_iterator, 1);
11966 break;
11967 }
11968
11969 case value_t::null:
11970 case value_t::string:
11971 case value_t::boolean:
11975 case value_t::binary:
11976 case value_t::discarded:
11977 default:
11978 {
11980 break;
11981 }
11982 }
11983
11984 return *this;
11985 }
11986
11991 iter_impl const operator--(int) // NOLINT(readability-const-return-type)
11992 {
11993 auto result = *this;
11994 --(*this);
11995 return result;
11996 }
11997
12003 {
12004 JSON_ASSERT(m_object != nullptr);
12005
12006 switch (m_object->m_type)
12007 {
12008 case value_t::object:
12009 {
12010 std::advance(m_it.object_iterator, -1);
12011 break;
12012 }
12013
12014 case value_t::array:
12015 {
12016 std::advance(m_it.array_iterator, -1);
12017 break;
12018 }
12019
12020 case value_t::null:
12021 case value_t::string:
12022 case value_t::boolean:
12026 case value_t::binary:
12027 case value_t::discarded:
12028 default:
12029 {
12031 break;
12032 }
12033 }
12034
12035 return *this;
12036 }
12037
12042 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
12043 bool operator==(const IterImpl& other) const
12044 {
12045 // if objects are not the same, the comparison is undefined
12046 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12047 {
12048 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12049 }
12050
12051 JSON_ASSERT(m_object != nullptr);
12052
12053 switch (m_object->m_type)
12054 {
12055 case value_t::object:
12056 return (m_it.object_iterator == other.m_it.object_iterator);
12057
12058 case value_t::array:
12059 return (m_it.array_iterator == other.m_it.array_iterator);
12060
12061 case value_t::null:
12062 case value_t::string:
12063 case value_t::boolean:
12067 case value_t::binary:
12068 case value_t::discarded:
12069 default:
12070 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
12071 }
12072 }
12073
12078 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
12079 bool operator!=(const IterImpl& other) const
12080 {
12081 return !operator==(other);
12082 }
12083
12088 bool operator<(const iter_impl& other) const
12089 {
12090 // if objects are not the same, the comparison is undefined
12091 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12092 {
12093 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12094 }
12095
12096 JSON_ASSERT(m_object != nullptr);
12097
12098 switch (m_object->m_type)
12099 {
12100 case value_t::object:
12101 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
12102
12103 case value_t::array:
12104 return (m_it.array_iterator < other.m_it.array_iterator);
12105
12106 case value_t::null:
12107 case value_t::string:
12108 case value_t::boolean:
12112 case value_t::binary:
12113 case value_t::discarded:
12114 default:
12116 }
12117 }
12118
12123 bool operator<=(const iter_impl& other) const
12124 {
12125 return !other.operator < (*this);
12126 }
12127
12132 bool operator>(const iter_impl& other) const
12133 {
12134 return !operator<=(other);
12135 }
12136
12141 bool operator>=(const iter_impl& other) const
12142 {
12143 return !operator<(other);
12144 }
12145
12151 {
12152 JSON_ASSERT(m_object != nullptr);
12153
12154 switch (m_object->m_type)
12155 {
12156 case value_t::object:
12157 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12158
12159 case value_t::array:
12160 {
12161 std::advance(m_it.array_iterator, i);
12162 break;
12163 }
12164
12165 case value_t::null:
12166 case value_t::string:
12167 case value_t::boolean:
12171 case value_t::binary:
12172 case value_t::discarded:
12173 default:
12174 {
12176 break;
12177 }
12178 }
12179
12180 return *this;
12181 }
12182
12188 {
12189 return operator+=(-i);
12190 }
12191
12197 {
12198 auto result = *this;
12199 result += i;
12200 return result;
12201 }
12202
12208 {
12209 auto result = it;
12210 result += i;
12211 return result;
12212 }
12213
12219 {
12220 auto result = *this;
12221 result -= i;
12222 return result;
12223 }
12224
12230 {
12231 JSON_ASSERT(m_object != nullptr);
12232
12233 switch (m_object->m_type)
12234 {
12235 case value_t::object:
12236 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12237
12238 case value_t::array:
12239 return m_it.array_iterator - other.m_it.array_iterator;
12240
12241 case value_t::null:
12242 case value_t::string:
12243 case value_t::boolean:
12247 case value_t::binary:
12248 case value_t::discarded:
12249 default:
12251 }
12252 }
12253
12259 {
12260 JSON_ASSERT(m_object != nullptr);
12261
12262 switch (m_object->m_type)
12263 {
12264 case value_t::object:
12265 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
12266
12267 case value_t::array:
12268 return *std::next(m_it.array_iterator, n);
12269
12270 case value_t::null:
12271 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12272
12273 case value_t::string:
12274 case value_t::boolean:
12278 case value_t::binary:
12279 case value_t::discarded:
12280 default:
12281 {
12283 {
12284 return *m_object;
12285 }
12286
12287 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12288 }
12289 }
12290 }
12291
12296 const typename object_t::key_type& key() const
12297 {
12298 JSON_ASSERT(m_object != nullptr);
12299
12300 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
12301 {
12302 return m_it.object_iterator->first;
12303 }
12304
12305 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
12306 }
12307
12313 {
12314 return operator*();
12315 }
12316
12319 pointer m_object = nullptr;
12322};
12323} // namespace detail
12324} // namespace nlohmann
12325
12326// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
12327
12328// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
12329
12330
12331#include <cstddef> // ptrdiff_t
12332#include <iterator> // reverse_iterator
12333#include <utility> // declval
12334
12335namespace nlohmann
12336{
12337namespace detail
12338{
12340// reverse_iterator //
12342
12361template<typename Base>
12362class json_reverse_iterator : public std::reverse_iterator<Base>
12363{
12364 public:
12365 using difference_type = std::ptrdiff_t;
12367 using base_iterator = std::reverse_iterator<Base>;
12369 using reference = typename Base::reference;
12370
12372 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
12373 : base_iterator(it) {}
12374
12376 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
12377
12379 json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
12380 {
12381 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12382 }
12383
12386 {
12387 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
12388 }
12389
12391 json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
12392 {
12393 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12394 }
12395
12398 {
12399 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
12400 }
12401
12404 {
12405 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
12406 }
12407
12410 {
12411 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12412 }
12413
12416 {
12417 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12418 }
12419
12422 {
12423 return base_iterator(*this) - base_iterator(other);
12424 }
12425
12428 {
12429 return *(this->operator+(n));
12430 }
12431
12433 auto key() const -> decltype(std::declval<Base>().key())
12434 {
12435 auto it = --this->base();
12436 return it.key();
12437 }
12438
12441 {
12442 auto it = --this->base();
12443 return it.operator * ();
12444 }
12445};
12446} // namespace detail
12447} // namespace nlohmann
12448
12449// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12450
12451// #include <nlohmann/detail/json_pointer.hpp>
12452
12453
12454#include <algorithm> // all_of
12455#include <cctype> // isdigit
12456#include <limits> // max
12457#include <numeric> // accumulate
12458#include <string> // string
12459#include <utility> // move
12460#include <vector> // vector
12461
12462// #include <nlohmann/detail/exceptions.hpp>
12463
12464// #include <nlohmann/detail/macro_scope.hpp>
12465
12466// #include <nlohmann/detail/string_escape.hpp>
12467
12468// #include <nlohmann/detail/value_t.hpp>
12469
12470
12471namespace nlohmann
12472{
12473template<typename BasicJsonType>
12475{
12476 // allow basic_json to access private members
12478 friend class basic_json;
12479
12480 public:
12502 explicit json_pointer(const std::string& s = "")
12504 {}
12505
12520 std::string to_string() const
12521 {
12522 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
12523 std::string{},
12524 [](const std::string & a, const std::string & b)
12525 {
12526 return a + "/" + detail::escape(b);
12527 });
12528 }
12529
12531 operator std::string() const
12532 {
12533 return to_string();
12534 }
12535
12553 {
12555 ptr.reference_tokens.begin(),
12556 ptr.reference_tokens.end());
12557 return *this;
12558 }
12559
12576 json_pointer& operator/=(std::string token)
12577 {
12578 push_back(std::move(token));
12579 return *this;
12580 }
12581
12598 json_pointer& operator/=(std::size_t array_idx)
12599 {
12600 return *this /= std::to_string(array_idx);
12601 }
12602
12619 const json_pointer& rhs)
12620 {
12621 return json_pointer(lhs) /= rhs;
12622 }
12623
12639 friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param)
12640 {
12641 return json_pointer(ptr) /= std::move(token);
12642 }
12643
12659 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
12660 {
12661 return json_pointer(ptr) /= array_idx;
12662 }
12663
12678 {
12679 if (empty())
12680 {
12681 return *this;
12682 }
12683
12684 json_pointer res = *this;
12685 res.pop_back();
12686 return res;
12687 }
12688
12703 {
12705 {
12706 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12707 }
12708
12709 reference_tokens.pop_back();
12710 }
12711
12726 const std::string& back() const
12727 {
12729 {
12730 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12731 }
12732
12733 return reference_tokens.back();
12734 }
12735
12748 void push_back(const std::string& token)
12749 {
12750 reference_tokens.push_back(token);
12751 }
12752
12754 void push_back(std::string&& token)
12755 {
12756 reference_tokens.push_back(std::move(token));
12757 }
12758
12773 bool empty() const noexcept
12774 {
12775 return reference_tokens.empty();
12776 }
12777
12778 private:
12789 static typename BasicJsonType::size_type array_index(const std::string& s)
12790 {
12791 using size_type = typename BasicJsonType::size_type;
12792
12793 // error condition (cf. RFC 6901, Sect. 4)
12794 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
12795 {
12796 JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
12797 }
12798
12799 // error condition (cf. RFC 6901, Sect. 4)
12800 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
12801 {
12802 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
12803 }
12804
12805 std::size_t processed_chars = 0;
12806 unsigned long long res = 0; // NOLINT(runtime/int)
12807 JSON_TRY
12808 {
12809 res = std::stoull(s, &processed_chars);
12810 }
12811 JSON_CATCH(std::out_of_range&)
12812 {
12813 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12814 }
12815
12816 // check if the string was completely read
12817 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
12818 {
12819 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12820 }
12821
12822 // only triggered on special platforms (like 32bit), see also
12823 // https://github.com/nlohmann/json/pull/2203
12824 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
12825 {
12826 JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
12827 }
12828
12829 return static_cast<size_type>(res);
12830 }
12831
12833 json_pointer top() const
12834 {
12836 {
12837 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12838 }
12839
12842 return result;
12843 }
12844
12845 private:
12855 {
12856 auto* result = &j;
12857
12858 // in case no reference tokens exist, return a reference to the JSON value
12859 // j which will be overwritten by a primitive value
12860 for (const auto& reference_token : reference_tokens)
12861 {
12862 switch (result->type())
12863 {
12865 {
12866 if (reference_token == "0")
12867 {
12868 // start a new array if reference token is 0
12869 result = &result->operator[](0);
12870 }
12871 else
12872 {
12873 // start a new object otherwise
12874 result = &result->operator[](reference_token);
12875 }
12876 break;
12877 }
12878
12880 {
12881 // create an entry in the object
12882 result = &result->operator[](reference_token);
12883 break;
12884 }
12885
12887 {
12888 // create an entry in the array
12889 result = &result->operator[](array_index(reference_token));
12890 break;
12891 }
12892
12893 /*
12894 The following code is only reached if there exists a reference
12895 token _and_ the current value is primitive. In this case, we have
12896 an error situation, because primitive values may only occur as
12897 single value; that is, with an empty list of reference tokens.
12898 */
12906 default:
12907 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
12908 }
12909 }
12910
12911 return *result;
12912 }
12913
12934 {
12935 for (const auto& reference_token : reference_tokens)
12936 {
12937 // convert null values to arrays or objects before continuing
12938 if (ptr->is_null())
12939 {
12940 // check if reference token is a number
12941 const bool nums =
12942 std::all_of(reference_token.begin(), reference_token.end(),
12943 [](const unsigned char x)
12944 {
12945 return std::isdigit(x);
12946 });
12947
12948 // change value to array for numbers or "-" or to object otherwise
12949 *ptr = (nums || reference_token == "-")
12952 }
12953
12954 switch (ptr->type())
12955 {
12957 {
12958 // use unchecked object access
12959 ptr = &ptr->operator[](reference_token);
12960 break;
12961 }
12962
12964 {
12965 if (reference_token == "-")
12966 {
12967 // explicitly treat "-" as index beyond the end
12968 ptr = &ptr->operator[](ptr->m_value.array->size());
12969 }
12970 else
12971 {
12972 // convert array index to number; unchecked access
12973 ptr = &ptr->operator[](array_index(reference_token));
12974 }
12975 break;
12976 }
12977
12986 default:
12987 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12988 }
12989 }
12990
12991 return *ptr;
12992 }
12993
13001 {
13002 for (const auto& reference_token : reference_tokens)
13003 {
13004 switch (ptr->type())
13005 {
13007 {
13008 // note: at performs range check
13009 ptr = &ptr->at(reference_token);
13010 break;
13011 }
13012
13014 {
13015 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13016 {
13017 // "-" always fails the range check
13019 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13020 ") is out of range", *ptr));
13021 }
13022
13023 // note: at performs range check
13024 ptr = &ptr->at(array_index(reference_token));
13025 break;
13026 }
13027
13036 default:
13037 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13038 }
13039 }
13040
13041 return *ptr;
13042 }
13043
13058 {
13059 for (const auto& reference_token : reference_tokens)
13060 {
13061 switch (ptr->type())
13062 {
13064 {
13065 // use unchecked object access
13066 ptr = &ptr->operator[](reference_token);
13067 break;
13068 }
13069
13071 {
13072 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13073 {
13074 // "-" cannot be used for const access
13075 JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
13076 }
13077
13078 // use unchecked array access
13079 ptr = &ptr->operator[](array_index(reference_token));
13080 break;
13081 }
13082
13091 default:
13092 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13093 }
13094 }
13095
13096 return *ptr;
13097 }
13098
13105 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
13106 {
13107 for (const auto& reference_token : reference_tokens)
13108 {
13109 switch (ptr->type())
13110 {
13112 {
13113 // note: at performs range check
13114 ptr = &ptr->at(reference_token);
13115 break;
13116 }
13117
13119 {
13120 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13121 {
13122 // "-" always fails the range check
13124 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13125 ") is out of range", *ptr));
13126 }
13127
13128 // note: at performs range check
13129 ptr = &ptr->at(array_index(reference_token));
13130 break;
13131 }
13132
13141 default:
13142 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13143 }
13144 }
13145
13146 return *ptr;
13147 }
13148
13153 bool contains(const BasicJsonType* ptr) const
13154 {
13155 for (const auto& reference_token : reference_tokens)
13156 {
13157 switch (ptr->type())
13158 {
13160 {
13161 if (!ptr->contains(reference_token))
13162 {
13163 // we did not find the key in the object
13164 return false;
13165 }
13166
13167 ptr = &ptr->operator[](reference_token);
13168 break;
13169 }
13170
13172 {
13173 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13174 {
13175 // "-" always fails the range check
13176 return false;
13177 }
13178 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
13179 {
13180 // invalid char
13181 return false;
13182 }
13183 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
13184 {
13185 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
13186 {
13187 // first char should be between '1' and '9'
13188 return false;
13189 }
13190 for (std::size_t i = 1; i < reference_token.size(); i++)
13191 {
13192 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
13193 {
13194 // other char should be between '0' and '9'
13195 return false;
13196 }
13197 }
13198 }
13199
13200 const auto idx = array_index(reference_token);
13201 if (idx >= ptr->size())
13202 {
13203 // index out of range
13204 return false;
13205 }
13206
13207 ptr = &ptr->operator[](idx);
13208 break;
13209 }
13210
13219 default:
13220 {
13221 // we do not expect primitive values if there is still a
13222 // reference token to process
13223 return false;
13224 }
13225 }
13226 }
13227
13228 // no reference token left means we found a primitive value
13229 return true;
13230 }
13231
13241 static std::vector<std::string> split(const std::string& reference_string)
13242 {
13243 std::vector<std::string> result;
13244
13245 // special case: empty reference string -> no reference tokens
13246 if (reference_string.empty())
13247 {
13248 return result;
13249 }
13250
13251 // check if nonempty reference string begins with slash
13252 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
13253 {
13254 JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
13255 }
13256
13257 // extract the reference tokens:
13258 // - slash: position of the last read slash (or end of string)
13259 // - start: position after the previous slash
13260 for (
13261 // search for the first slash after the first character
13262 std::size_t slash = reference_string.find_first_of('/', 1),
13263 // set the beginning of the first reference token
13264 start = 1;
13265 // we can stop if start == 0 (if slash == std::string::npos)
13266 start != 0;
13267 // set the beginning of the next reference token
13268 // (will eventually be 0 if slash == std::string::npos)
13269 start = (slash == std::string::npos) ? 0 : slash + 1,
13270 // find next slash
13271 slash = reference_string.find_first_of('/', start))
13272 {
13273 // use the text between the beginning of the reference token
13274 // (start) and the last slash (slash).
13275 auto reference_token = reference_string.substr(start, slash - start);
13276
13277 // check reference tokens are properly escaped
13278 for (std::size_t pos = reference_token.find_first_of('~');
13279 pos != std::string::npos;
13280 pos = reference_token.find_first_of('~', pos + 1))
13281 {
13282 JSON_ASSERT(reference_token[pos] == '~');
13283
13284 // ~ must be followed by 0 or 1
13285 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
13286 (reference_token[pos + 1] != '0' &&
13287 reference_token[pos + 1] != '1')))
13288 {
13289 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
13290 }
13291 }
13292
13293 // finally, store the reference token
13294 detail::unescape(reference_token);
13295 result.push_back(reference_token);
13296 }
13297
13298 return result;
13299 }
13300
13301 private:
13309 static void flatten(const std::string& reference_string,
13310 const BasicJsonType& value,
13312 {
13313 switch (value.type())
13314 {
13316 {
13317 if (value.m_value.array->empty())
13318 {
13319 // flatten empty array as null
13320 result[reference_string] = nullptr;
13321 }
13322 else
13323 {
13324 // iterate array and use index as reference string
13325 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13326 {
13327 flatten(reference_string + "/" + std::to_string(i),
13328 value.m_value.array->operator[](i), result);
13329 }
13330 }
13331 break;
13332 }
13333
13335 {
13336 if (value.m_value.object->empty())
13337 {
13338 // flatten empty object as null
13339 result[reference_string] = nullptr;
13340 }
13341 else
13342 {
13343 // iterate object and use keys as reference string
13344 for (const auto& element : *value.m_value.object)
13345 {
13346 flatten(reference_string + "/" + detail::escape(element.first), element.second, result);
13347 }
13348 }
13349 break;
13350 }
13351
13360 default:
13361 {
13362 // add primitive value with its reference string
13363 result[reference_string] = value;
13364 break;
13365 }
13366 }
13367 }
13368
13379 static BasicJsonType
13381 {
13382 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
13383 {
13384 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
13385 }
13386
13388
13389 // iterate the JSON object values
13390 for (const auto& element : *value.m_value.object)
13391 {
13392 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
13393 {
13394 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
13395 }
13396
13397 // assign value to reference pointed to by JSON pointer; Note that if
13398 // the JSON pointer is "" (i.e., points to the whole value), function
13399 // get_and_create returns a reference to result itself. An assignment
13400 // will then create a primitive value.
13401 json_pointer(element.first).get_and_create(result) = element.second;
13402 }
13403
13404 return result;
13405 }
13406
13418 friend bool operator==(json_pointer const& lhs,
13419 json_pointer const& rhs) noexcept
13420 {
13421 return lhs.reference_tokens == rhs.reference_tokens;
13422 }
13423
13435 friend bool operator!=(json_pointer const& lhs,
13436 json_pointer const& rhs) noexcept
13437 {
13438 return !(lhs == rhs);
13439 }
13440
13442 std::vector<std::string> reference_tokens;
13443};
13444} // namespace nlohmann
13445
13446// #include <nlohmann/detail/json_ref.hpp>
13447
13448
13449#include <initializer_list>
13450#include <utility>
13451
13452// #include <nlohmann/detail/meta/type_traits.hpp>
13453
13454
13455namespace nlohmann
13456{
13457namespace detail
13458{
13459template<typename BasicJsonType>
13461{
13462 public:
13463 using value_type = BasicJsonType;
13464
13466 : owned_value(std::move(value))
13467 {}
13468
13470 : value_ref(&value)
13471 {}
13472
13473 json_ref(std::initializer_list<json_ref> init)
13474 : owned_value(init)
13475 {}
13476
13477 template <
13478 class... Args,
13479 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
13480 json_ref(Args && ... args)
13481 : owned_value(std::forward<Args>(args)...)
13482 {}
13483
13484 // class should be movable only
13485 json_ref(json_ref&&) noexcept = default;
13486 json_ref(const json_ref&) = delete;
13487 json_ref& operator=(const json_ref&) = delete;
13488 json_ref& operator=(json_ref&&) = delete;
13489 ~json_ref() = default;
13490
13492 {
13493 if (value_ref == nullptr)
13494 {
13495 return std::move(owned_value);
13496 }
13497 return *value_ref;
13498 }
13499
13500 value_type const& operator*() const
13501 {
13502 return value_ref ? *value_ref : owned_value;
13503 }
13504
13505 value_type const* operator->() const
13506 {
13507 return &** this;
13508 }
13509
13510 private:
13511 mutable value_type owned_value = nullptr;
13512 value_type const* value_ref = nullptr;
13513};
13514} // namespace detail
13515} // namespace nlohmann
13516
13517// #include <nlohmann/detail/macro_scope.hpp>
13518
13519// #include <nlohmann/detail/string_escape.hpp>
13520
13521// #include <nlohmann/detail/meta/cpp_future.hpp>
13522
13523// #include <nlohmann/detail/meta/type_traits.hpp>
13524
13525// #include <nlohmann/detail/output/binary_writer.hpp>
13526
13527
13528#include <algorithm> // reverse
13529#include <array> // array
13530#include <cmath> // isnan, isinf
13531#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13532#include <cstring> // memcpy
13533#include <limits> // numeric_limits
13534#include <string> // string
13535#include <utility> // move
13536
13537// #include <nlohmann/detail/input/binary_reader.hpp>
13538
13539// #include <nlohmann/detail/macro_scope.hpp>
13540
13541// #include <nlohmann/detail/output/output_adapters.hpp>
13542
13543
13544#include <algorithm> // copy
13545#include <cstddef> // size_t
13546#include <iterator> // back_inserter
13547#include <memory> // shared_ptr, make_shared
13548#include <string> // basic_string
13549#include <vector> // vector
13550
13551#ifndef JSON_NO_IO
13552 #include <ios> // streamsize
13553 #include <ostream> // basic_ostream
13554#endif // JSON_NO_IO
13555
13556// #include <nlohmann/detail/macro_scope.hpp>
13557
13558
13559namespace nlohmann
13560{
13561namespace detail
13562{
13564template<typename CharType> struct output_adapter_protocol
13565{
13566 virtual void write_character(CharType c) = 0;
13567 virtual void write_characters(const CharType* s, std::size_t length) = 0;
13568 virtual ~output_adapter_protocol() = default;
13569
13574 output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
13575};
13576
13578template<typename CharType>
13579using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13580
13582template<typename CharType, typename AllocatorType = std::allocator<CharType>>
13584{
13585 public:
13586 explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
13587 : v(vec)
13588 {}
13589
13590 void write_character(CharType c) override
13591 {
13592 v.push_back(c);
13593 }
13594
13596 void write_characters(const CharType* s, std::size_t length) override
13597 {
13598 std::copy(s, s + length, std::back_inserter(v));
13599 }
13600
13601 private:
13602 std::vector<CharType, AllocatorType>& v;
13603};
13604
13605#ifndef JSON_NO_IO
13607template<typename CharType>
13609{
13610 public:
13611 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
13612 : stream(s)
13613 {}
13614
13615 void write_character(CharType c) override
13616 {
13617 stream.put(c);
13618 }
13619
13621 void write_characters(const CharType* s, std::size_t length) override
13622 {
13623 stream.write(s, static_cast<std::streamsize>(length));
13624 }
13625
13626 private:
13627 std::basic_ostream<CharType>& stream;
13628};
13629#endif // JSON_NO_IO
13630
13632template<typename CharType, typename StringType = std::basic_string<CharType>>
13634{
13635 public:
13636 explicit output_string_adapter(StringType& s) noexcept
13637 : str(s)
13638 {}
13639
13640 void write_character(CharType c) override
13641 {
13642 str.push_back(c);
13643 }
13644
13646 void write_characters(const CharType* s, std::size_t length) override
13647 {
13648 str.append(s, length);
13649 }
13650
13651 private:
13652 StringType& str;
13653};
13654
13655template<typename CharType, typename StringType = std::basic_string<CharType>>
13657{
13658 public:
13659 template<typename AllocatorType = std::allocator<CharType>>
13660 output_adapter(std::vector<CharType, AllocatorType>& vec)
13661 : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
13662
13663#ifndef JSON_NO_IO
13664 output_adapter(std::basic_ostream<CharType>& s)
13665 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
13666#endif // JSON_NO_IO
13667
13668 output_adapter(StringType& s)
13669 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
13670
13672 {
13673 return oa;
13674 }
13675
13676 private:
13678};
13679} // namespace detail
13680} // namespace nlohmann
13681
13682
13683namespace nlohmann
13684{
13685namespace detail
13686{
13688// binary writer //
13690
13694template<typename BasicJsonType, typename CharType>
13696{
13697 using string_t = typename BasicJsonType::string_t;
13698 using binary_t = typename BasicJsonType::binary_t;
13699 using number_float_t = typename BasicJsonType::number_float_t;
13700
13701 public:
13707 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
13708 {
13709 JSON_ASSERT(oa);
13710 }
13711
13716 void write_bson(const BasicJsonType& j)
13717 {
13718 switch (j.type())
13719 {
13720 case value_t::object:
13721 {
13722 write_bson_object(*j.m_value.object);
13723 break;
13724 }
13725
13726 case value_t::null:
13727 case value_t::array:
13728 case value_t::string:
13729 case value_t::boolean:
13730 case value_t::number_integer:
13731 case value_t::number_unsigned:
13732 case value_t::number_float:
13733 case value_t::binary:
13734 case value_t::discarded:
13735 default:
13736 {
13737 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));
13738 }
13739 }
13740 }
13741
13745 void write_cbor(const BasicJsonType& j)
13746 {
13747 switch (j.type())
13748 {
13749 case value_t::null:
13750 {
13751 oa->write_character(to_char_type(0xF6));
13752 break;
13753 }
13754
13755 case value_t::boolean:
13756 {
13757 oa->write_character(j.m_value.boolean
13758 ? to_char_type(0xF5)
13759 : to_char_type(0xF4));
13760 break;
13761 }
13762
13763 case value_t::number_integer:
13764 {
13765 if (j.m_value.number_integer >= 0)
13766 {
13767 // CBOR does not differentiate between positive signed
13768 // integers and unsigned integers. Therefore, we used the
13769 // code from the value_t::number_unsigned case here.
13770 if (j.m_value.number_integer <= 0x17)
13771 {
13772 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13773 }
13774 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
13775 {
13776 oa->write_character(to_char_type(0x18));
13777 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13778 }
13779 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
13780 {
13781 oa->write_character(to_char_type(0x19));
13782 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13783 }
13784 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
13785 {
13786 oa->write_character(to_char_type(0x1A));
13787 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13788 }
13789 else
13790 {
13791 oa->write_character(to_char_type(0x1B));
13792 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13793 }
13794 }
13795 else
13796 {
13797 // The conversions below encode the sign in the first
13798 // byte, and the value is converted to a positive number.
13799 const auto positive_number = -1 - j.m_value.number_integer;
13800 if (j.m_value.number_integer >= -24)
13801 {
13802 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
13803 }
13804 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
13805 {
13806 oa->write_character(to_char_type(0x38));
13807 write_number(static_cast<std::uint8_t>(positive_number));
13808 }
13809 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
13810 {
13811 oa->write_character(to_char_type(0x39));
13812 write_number(static_cast<std::uint16_t>(positive_number));
13813 }
13814 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
13815 {
13816 oa->write_character(to_char_type(0x3A));
13817 write_number(static_cast<std::uint32_t>(positive_number));
13818 }
13819 else
13820 {
13821 oa->write_character(to_char_type(0x3B));
13822 write_number(static_cast<std::uint64_t>(positive_number));
13823 }
13824 }
13825 break;
13826 }
13827
13828 case value_t::number_unsigned:
13829 {
13830 if (j.m_value.number_unsigned <= 0x17)
13831 {
13832 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13833 }
13834 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13835 {
13836 oa->write_character(to_char_type(0x18));
13837 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13838 }
13839 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13840 {
13841 oa->write_character(to_char_type(0x19));
13842 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
13843 }
13844 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13845 {
13846 oa->write_character(to_char_type(0x1A));
13847 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
13848 }
13849 else
13850 {
13851 oa->write_character(to_char_type(0x1B));
13852 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
13853 }
13854 break;
13855 }
13856
13857 case value_t::number_float:
13858 {
13859 if (std::isnan(j.m_value.number_float))
13860 {
13861 // NaN is 0xf97e00 in CBOR
13862 oa->write_character(to_char_type(0xF9));
13863 oa->write_character(to_char_type(0x7E));
13864 oa->write_character(to_char_type(0x00));
13865 }
13866 else if (std::isinf(j.m_value.number_float))
13867 {
13868 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
13869 oa->write_character(to_char_type(0xf9));
13870 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
13871 oa->write_character(to_char_type(0x00));
13872 }
13873 else
13874 {
13875 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
13876 }
13877 break;
13878 }
13879
13880 case value_t::string:
13881 {
13882 // step 1: write control byte and the string length
13883 const auto N = j.m_value.string->size();
13884 if (N <= 0x17)
13885 {
13886 write_number(static_cast<std::uint8_t>(0x60 + N));
13887 }
13888 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13889 {
13890 oa->write_character(to_char_type(0x78));
13891 write_number(static_cast<std::uint8_t>(N));
13892 }
13893 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13894 {
13895 oa->write_character(to_char_type(0x79));
13896 write_number(static_cast<std::uint16_t>(N));
13897 }
13898 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13899 {
13900 oa->write_character(to_char_type(0x7A));
13901 write_number(static_cast<std::uint32_t>(N));
13902 }
13903 // LCOV_EXCL_START
13904 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13905 {
13906 oa->write_character(to_char_type(0x7B));
13907 write_number(static_cast<std::uint64_t>(N));
13908 }
13909 // LCOV_EXCL_STOP
13910
13911 // step 2: write the string
13912 oa->write_characters(
13913 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13914 j.m_value.string->size());
13915 break;
13916 }
13917
13918 case value_t::array:
13919 {
13920 // step 1: write control byte and the array size
13921 const auto N = j.m_value.array->size();
13922 if (N <= 0x17)
13923 {
13924 write_number(static_cast<std::uint8_t>(0x80 + N));
13925 }
13926 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13927 {
13928 oa->write_character(to_char_type(0x98));
13929 write_number(static_cast<std::uint8_t>(N));
13930 }
13931 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13932 {
13933 oa->write_character(to_char_type(0x99));
13934 write_number(static_cast<std::uint16_t>(N));
13935 }
13936 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13937 {
13938 oa->write_character(to_char_type(0x9A));
13939 write_number(static_cast<std::uint32_t>(N));
13940 }
13941 // LCOV_EXCL_START
13942 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13943 {
13944 oa->write_character(to_char_type(0x9B));
13945 write_number(static_cast<std::uint64_t>(N));
13946 }
13947 // LCOV_EXCL_STOP
13948
13949 // step 2: write each element
13950 for (const auto& el : *j.m_value.array)
13951 {
13952 write_cbor(el);
13953 }
13954 break;
13955 }
13956
13957 case value_t::binary:
13958 {
13959 if (j.m_value.binary->has_subtype())
13960 {
13961 if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
13962 {
13963 write_number(static_cast<std::uint8_t>(0xd8));
13964 write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
13965 }
13966 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
13967 {
13968 write_number(static_cast<std::uint8_t>(0xd9));
13969 write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
13970 }
13971 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
13972 {
13973 write_number(static_cast<std::uint8_t>(0xda));
13974 write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
13975 }
13976 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
13977 {
13978 write_number(static_cast<std::uint8_t>(0xdb));
13979 write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
13980 }
13981 }
13982
13983 // step 1: write control byte and the binary array size
13984 const auto N = j.m_value.binary->size();
13985 if (N <= 0x17)
13986 {
13987 write_number(static_cast<std::uint8_t>(0x40 + N));
13988 }
13989 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13990 {
13991 oa->write_character(to_char_type(0x58));
13992 write_number(static_cast<std::uint8_t>(N));
13993 }
13994 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13995 {
13996 oa->write_character(to_char_type(0x59));
13997 write_number(static_cast<std::uint16_t>(N));
13998 }
13999 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14000 {
14001 oa->write_character(to_char_type(0x5A));
14002 write_number(static_cast<std::uint32_t>(N));
14003 }
14004 // LCOV_EXCL_START
14005 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14006 {
14007 oa->write_character(to_char_type(0x5B));
14008 write_number(static_cast<std::uint64_t>(N));
14009 }
14010 // LCOV_EXCL_STOP
14011
14012 // step 2: write each element
14013 oa->write_characters(
14014 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14015 N);
14016
14017 break;
14018 }
14019
14020 case value_t::object:
14021 {
14022 // step 1: write control byte and the object size
14023 const auto N = j.m_value.object->size();
14024 if (N <= 0x17)
14025 {
14026 write_number(static_cast<std::uint8_t>(0xA0 + N));
14027 }
14028 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14029 {
14030 oa->write_character(to_char_type(0xB8));
14031 write_number(static_cast<std::uint8_t>(N));
14032 }
14033 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14034 {
14035 oa->write_character(to_char_type(0xB9));
14036 write_number(static_cast<std::uint16_t>(N));
14037 }
14038 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14039 {
14040 oa->write_character(to_char_type(0xBA));
14041 write_number(static_cast<std::uint32_t>(N));
14042 }
14043 // LCOV_EXCL_START
14044 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14045 {
14046 oa->write_character(to_char_type(0xBB));
14047 write_number(static_cast<std::uint64_t>(N));
14048 }
14049 // LCOV_EXCL_STOP
14050
14051 // step 2: write each element
14052 for (const auto& el : *j.m_value.object)
14053 {
14054 write_cbor(el.first);
14055 write_cbor(el.second);
14056 }
14057 break;
14058 }
14059
14060 case value_t::discarded:
14061 default:
14062 break;
14063 }
14064 }
14065
14069 void write_msgpack(const BasicJsonType& j)
14070 {
14071 switch (j.type())
14072 {
14073 case value_t::null: // nil
14074 {
14075 oa->write_character(to_char_type(0xC0));
14076 break;
14077 }
14078
14079 case value_t::boolean: // true and false
14080 {
14081 oa->write_character(j.m_value.boolean
14082 ? to_char_type(0xC3)
14083 : to_char_type(0xC2));
14084 break;
14085 }
14086
14087 case value_t::number_integer:
14088 {
14089 if (j.m_value.number_integer >= 0)
14090 {
14091 // MessagePack does not differentiate between positive
14092 // signed integers and unsigned integers. Therefore, we used
14093 // the code from the value_t::number_unsigned case here.
14094 if (j.m_value.number_unsigned < 128)
14095 {
14096 // positive fixnum
14097 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14098 }
14099 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14100 {
14101 // uint 8
14102 oa->write_character(to_char_type(0xCC));
14103 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14104 }
14105 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14106 {
14107 // uint 16
14108 oa->write_character(to_char_type(0xCD));
14109 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14110 }
14111 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14112 {
14113 // uint 32
14114 oa->write_character(to_char_type(0xCE));
14115 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14116 }
14117 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14118 {
14119 // uint 64
14120 oa->write_character(to_char_type(0xCF));
14121 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14122 }
14123 }
14124 else
14125 {
14126 if (j.m_value.number_integer >= -32)
14127 {
14128 // negative fixnum
14129 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14130 }
14131 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
14132 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14133 {
14134 // int 8
14135 oa->write_character(to_char_type(0xD0));
14136 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14137 }
14138 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
14139 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14140 {
14141 // int 16
14142 oa->write_character(to_char_type(0xD1));
14143 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
14144 }
14145 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
14146 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14147 {
14148 // int 32
14149 oa->write_character(to_char_type(0xD2));
14150 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
14151 }
14152 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
14153 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14154 {
14155 // int 64
14156 oa->write_character(to_char_type(0xD3));
14157 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
14158 }
14159 }
14160 break;
14161 }
14162
14163 case value_t::number_unsigned:
14164 {
14165 if (j.m_value.number_unsigned < 128)
14166 {
14167 // positive fixnum
14168 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14169 }
14170 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14171 {
14172 // uint 8
14173 oa->write_character(to_char_type(0xCC));
14174 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14175 }
14176 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14177 {
14178 // uint 16
14179 oa->write_character(to_char_type(0xCD));
14180 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14181 }
14182 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14183 {
14184 // uint 32
14185 oa->write_character(to_char_type(0xCE));
14186 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14187 }
14188 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14189 {
14190 // uint 64
14191 oa->write_character(to_char_type(0xCF));
14192 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14193 }
14194 break;
14195 }
14196
14197 case value_t::number_float:
14198 {
14199 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
14200 break;
14201 }
14202
14203 case value_t::string:
14204 {
14205 // step 1: write control byte and the string length
14206 const auto N = j.m_value.string->size();
14207 if (N <= 31)
14208 {
14209 // fixstr
14210 write_number(static_cast<std::uint8_t>(0xA0 | N));
14211 }
14212 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14213 {
14214 // str 8
14215 oa->write_character(to_char_type(0xD9));
14216 write_number(static_cast<std::uint8_t>(N));
14217 }
14218 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14219 {
14220 // str 16
14221 oa->write_character(to_char_type(0xDA));
14222 write_number(static_cast<std::uint16_t>(N));
14223 }
14224 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14225 {
14226 // str 32
14227 oa->write_character(to_char_type(0xDB));
14228 write_number(static_cast<std::uint32_t>(N));
14229 }
14230
14231 // step 2: write the string
14232 oa->write_characters(
14233 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14234 j.m_value.string->size());
14235 break;
14236 }
14237
14238 case value_t::array:
14239 {
14240 // step 1: write control byte and the array size
14241 const auto N = j.m_value.array->size();
14242 if (N <= 15)
14243 {
14244 // fixarray
14245 write_number(static_cast<std::uint8_t>(0x90 | N));
14246 }
14247 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14248 {
14249 // array 16
14250 oa->write_character(to_char_type(0xDC));
14251 write_number(static_cast<std::uint16_t>(N));
14252 }
14253 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14254 {
14255 // array 32
14256 oa->write_character(to_char_type(0xDD));
14257 write_number(static_cast<std::uint32_t>(N));
14258 }
14259
14260 // step 2: write each element
14261 for (const auto& el : *j.m_value.array)
14262 {
14263 write_msgpack(el);
14264 }
14265 break;
14266 }
14267
14268 case value_t::binary:
14269 {
14270 // step 0: determine if the binary type has a set subtype to
14271 // determine whether or not to use the ext or fixext types
14272 const bool use_ext = j.m_value.binary->has_subtype();
14273
14274 // step 1: write control byte and the byte string length
14275 const auto N = j.m_value.binary->size();
14276 if (N <= (std::numeric_limits<std::uint8_t>::max)())
14277 {
14278 std::uint8_t output_type{};
14279 bool fixed = true;
14280 if (use_ext)
14281 {
14282 switch (N)
14283 {
14284 case 1:
14285 output_type = 0xD4; // fixext 1
14286 break;
14287 case 2:
14288 output_type = 0xD5; // fixext 2
14289 break;
14290 case 4:
14291 output_type = 0xD6; // fixext 4
14292 break;
14293 case 8:
14294 output_type = 0xD7; // fixext 8
14295 break;
14296 case 16:
14297 output_type = 0xD8; // fixext 16
14298 break;
14299 default:
14300 output_type = 0xC7; // ext 8
14301 fixed = false;
14302 break;
14303 }
14304
14305 }
14306 else
14307 {
14308 output_type = 0xC4; // bin 8
14309 fixed = false;
14310 }
14311
14312 oa->write_character(to_char_type(output_type));
14313 if (!fixed)
14314 {
14315 write_number(static_cast<std::uint8_t>(N));
14316 }
14317 }
14318 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14319 {
14320 std::uint8_t output_type = use_ext
14321 ? 0xC8 // ext 16
14322 : 0xC5; // bin 16
14323
14324 oa->write_character(to_char_type(output_type));
14325 write_number(static_cast<std::uint16_t>(N));
14326 }
14327 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14328 {
14329 std::uint8_t output_type = use_ext
14330 ? 0xC9 // ext 32
14331 : 0xC6; // bin 32
14332
14333 oa->write_character(to_char_type(output_type));
14334 write_number(static_cast<std::uint32_t>(N));
14335 }
14336
14337 // step 1.5: if this is an ext type, write the subtype
14338 if (use_ext)
14339 {
14340 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
14341 }
14342
14343 // step 2: write the byte string
14344 oa->write_characters(
14345 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14346 N);
14347
14348 break;
14349 }
14350
14351 case value_t::object:
14352 {
14353 // step 1: write control byte and the object size
14354 const auto N = j.m_value.object->size();
14355 if (N <= 15)
14356 {
14357 // fixmap
14358 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
14359 }
14360 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14361 {
14362 // map 16
14363 oa->write_character(to_char_type(0xDE));
14364 write_number(static_cast<std::uint16_t>(N));
14365 }
14366 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14367 {
14368 // map 32
14369 oa->write_character(to_char_type(0xDF));
14370 write_number(static_cast<std::uint32_t>(N));
14371 }
14372
14373 // step 2: write each element
14374 for (const auto& el : *j.m_value.object)
14375 {
14376 write_msgpack(el.first);
14377 write_msgpack(el.second);
14378 }
14379 break;
14380 }
14381
14382 case value_t::discarded:
14383 default:
14384 break;
14385 }
14386 }
14387
14394 void write_ubjson(const BasicJsonType& j, const bool use_count,
14395 const bool use_type, const bool add_prefix = true)
14396 {
14397 switch (j.type())
14398 {
14399 case value_t::null:
14400 {
14401 if (add_prefix)
14402 {
14403 oa->write_character(to_char_type('Z'));
14404 }
14405 break;
14406 }
14407
14408 case value_t::boolean:
14409 {
14410 if (add_prefix)
14411 {
14412 oa->write_character(j.m_value.boolean
14413 ? to_char_type('T')
14414 : to_char_type('F'));
14415 }
14416 break;
14417 }
14418
14419 case value_t::number_integer:
14420 {
14421 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
14422 break;
14423 }
14424
14425 case value_t::number_unsigned:
14426 {
14427 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
14428 break;
14429 }
14430
14431 case value_t::number_float:
14432 {
14433 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
14434 break;
14435 }
14436
14437 case value_t::string:
14438 {
14439 if (add_prefix)
14440 {
14441 oa->write_character(to_char_type('S'));
14442 }
14443 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
14444 oa->write_characters(
14445 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14446 j.m_value.string->size());
14447 break;
14448 }
14449
14450 case value_t::array:
14451 {
14452 if (add_prefix)
14453 {
14454 oa->write_character(to_char_type('['));
14455 }
14456
14457 bool prefix_required = true;
14458 if (use_type && !j.m_value.array->empty())
14459 {
14460 JSON_ASSERT(use_count);
14461 const CharType first_prefix = ubjson_prefix(j.front());
14462 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14463 [this, first_prefix](const BasicJsonType & v)
14464 {
14465 return ubjson_prefix(v) == first_prefix;
14466 });
14467
14468 if (same_prefix)
14469 {
14470 prefix_required = false;
14471 oa->write_character(to_char_type('$'));
14472 oa->write_character(first_prefix);
14473 }
14474 }
14475
14476 if (use_count)
14477 {
14478 oa->write_character(to_char_type('#'));
14479 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
14480 }
14481
14482 for (const auto& el : *j.m_value.array)
14483 {
14484 write_ubjson(el, use_count, use_type, prefix_required);
14485 }
14486
14487 if (!use_count)
14488 {
14489 oa->write_character(to_char_type(']'));
14490 }
14491
14492 break;
14493 }
14494
14495 case value_t::binary:
14496 {
14497 if (add_prefix)
14498 {
14499 oa->write_character(to_char_type('['));
14500 }
14501
14502 if (use_type && !j.m_value.binary->empty())
14503 {
14504 JSON_ASSERT(use_count);
14505 oa->write_character(to_char_type('$'));
14506 oa->write_character('U');
14507 }
14508
14509 if (use_count)
14510 {
14511 oa->write_character(to_char_type('#'));
14512 write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
14513 }
14514
14515 if (use_type)
14516 {
14517 oa->write_characters(
14518 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14519 j.m_value.binary->size());
14520 }
14521 else
14522 {
14523 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14524 {
14525 oa->write_character(to_char_type('U'));
14526 oa->write_character(j.m_value.binary->data()[i]);
14527 }
14528 }
14529
14530 if (!use_count)
14531 {
14532 oa->write_character(to_char_type(']'));
14533 }
14534
14535 break;
14536 }
14537
14538 case value_t::object:
14539 {
14540 if (add_prefix)
14541 {
14542 oa->write_character(to_char_type('{'));
14543 }
14544
14545 bool prefix_required = true;
14546 if (use_type && !j.m_value.object->empty())
14547 {
14548 JSON_ASSERT(use_count);
14549 const CharType first_prefix = ubjson_prefix(j.front());
14550 const bool same_prefix = std::all_of(j.begin(), j.end(),
14551 [this, first_prefix](const BasicJsonType & v)
14552 {
14553 return ubjson_prefix(v) == first_prefix;
14554 });
14555
14556 if (same_prefix)
14557 {
14558 prefix_required = false;
14559 oa->write_character(to_char_type('$'));
14560 oa->write_character(first_prefix);
14561 }
14562 }
14563
14564 if (use_count)
14565 {
14566 oa->write_character(to_char_type('#'));
14567 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
14568 }
14569
14570 for (const auto& el : *j.m_value.object)
14571 {
14572 write_number_with_ubjson_prefix(el.first.size(), true);
14573 oa->write_characters(
14574 reinterpret_cast<const CharType*>(el.first.c_str()),
14575 el.first.size());
14576 write_ubjson(el.second, use_count, use_type, prefix_required);
14577 }
14578
14579 if (!use_count)
14580 {
14581 oa->write_character(to_char_type('}'));
14582 }
14583
14584 break;
14585 }
14586
14587 case value_t::discarded:
14588 default:
14589 break;
14590 }
14591 }
14592
14593 private:
14595 // BSON //
14597
14602 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
14603 {
14604 const auto it = name.find(static_cast<typename string_t::value_type>(0));
14605 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
14606 {
14607 JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
14608 static_cast<void>(j);
14609 }
14610
14611 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14612 }
14613
14618 const std::uint8_t element_type)
14619 {
14620 oa->write_character(to_char_type(element_type)); // boolean
14621 oa->write_characters(
14622 reinterpret_cast<const CharType*>(name.c_str()),
14623 name.size() + 1u);
14624 }
14625
14630 const bool value)
14631 {
14632 write_bson_entry_header(name, 0x08);
14633 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
14634 }
14635
14639 void write_bson_double(const string_t& name,
14640 const double value)
14641 {
14642 write_bson_entry_header(name, 0x01);
14643 write_number<double, true>(value);
14644 }
14645
14649 static std::size_t calc_bson_string_size(const string_t& value)
14650 {
14651 return sizeof(std::int32_t) + value.size() + 1ul;
14652 }
14653
14657 void write_bson_string(const string_t& name,
14658 const string_t& value)
14659 {
14660 write_bson_entry_header(name, 0x02);
14661
14662 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
14663 oa->write_characters(
14664 reinterpret_cast<const CharType*>(value.c_str()),
14665 value.size() + 1);
14666 }
14667
14671 void write_bson_null(const string_t& name)
14672 {
14673 write_bson_entry_header(name, 0x0A);
14674 }
14675
14679 static std::size_t calc_bson_integer_size(const std::int64_t value)
14680 {
14681 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
14682 ? sizeof(std::int32_t)
14683 : sizeof(std::int64_t);
14684 }
14685
14690 const std::int64_t value)
14691 {
14692 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
14693 {
14694 write_bson_entry_header(name, 0x10); // int32
14695 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
14696 }
14697 else
14698 {
14699 write_bson_entry_header(name, 0x12); // int64
14700 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
14701 }
14702 }
14703
14707 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
14708 {
14709 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14710 ? sizeof(std::int32_t)
14711 : sizeof(std::int64_t);
14712 }
14713
14718 const BasicJsonType& j)
14719 {
14720 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14721 {
14722 write_bson_entry_header(name, 0x10 /* int32 */);
14723 write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
14724 }
14725 else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14726 {
14727 write_bson_entry_header(name, 0x12 /* int64 */);
14728 write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
14729 }
14730 else
14731 {
14732 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(j.m_value.number_unsigned) + " cannot be represented by BSON as it does not fit int64", j));
14733 }
14734 }
14735
14740 const typename BasicJsonType::object_t& value)
14741 {
14742 write_bson_entry_header(name, 0x03); // object
14743 write_bson_object(value);
14744 }
14745
14749 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
14750 {
14751 std::size_t array_index = 0ul;
14752
14753 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
14754 {
14755 return result + calc_bson_element_size(std::to_string(array_index++), el);
14756 });
14757
14758 return sizeof(std::int32_t) + embedded_document_size + 1ul;
14759 }
14760
14764 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
14765 {
14766 return sizeof(std::int32_t) + value.size() + 1ul;
14767 }
14768
14772 void write_bson_array(const string_t& name,
14773 const typename BasicJsonType::array_t& value)
14774 {
14775 write_bson_entry_header(name, 0x04); // array
14776 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
14777
14778 std::size_t array_index = 0ul;
14779
14780 for (const auto& el : value)
14781 {
14782 write_bson_element(std::to_string(array_index++), el);
14783 }
14784
14785 oa->write_character(to_char_type(0x00));
14786 }
14787
14791 void write_bson_binary(const string_t& name,
14792 const binary_t& value)
14793 {
14794 write_bson_entry_header(name, 0x05);
14795
14796 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
14797 write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : std::uint8_t(0x00));
14798
14799 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
14800 }
14801
14806 static std::size_t calc_bson_element_size(const string_t& name,
14807 const BasicJsonType& j)
14808 {
14809 const auto header_size = calc_bson_entry_header_size(name, j);
14810 switch (j.type())
14811 {
14812 case value_t::object:
14813 return header_size + calc_bson_object_size(*j.m_value.object);
14814
14815 case value_t::array:
14816 return header_size + calc_bson_array_size(*j.m_value.array);
14817
14818 case value_t::binary:
14819 return header_size + calc_bson_binary_size(*j.m_value.binary);
14820
14821 case value_t::boolean:
14822 return header_size + 1ul;
14823
14824 case value_t::number_float:
14825 return header_size + 8ul;
14826
14827 case value_t::number_integer:
14828 return header_size + calc_bson_integer_size(j.m_value.number_integer);
14829
14830 case value_t::number_unsigned:
14831 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
14832
14833 case value_t::string:
14834 return header_size + calc_bson_string_size(*j.m_value.string);
14835
14836 case value_t::null:
14837 return header_size + 0ul;
14838
14839 // LCOV_EXCL_START
14840 case value_t::discarded:
14841 default:
14842 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14843 return 0ul;
14844 // LCOV_EXCL_STOP
14845 }
14846 }
14847
14855 const BasicJsonType& j)
14856 {
14857 switch (j.type())
14858 {
14859 case value_t::object:
14860 return write_bson_object_entry(name, *j.m_value.object);
14861
14862 case value_t::array:
14863 return write_bson_array(name, *j.m_value.array);
14864
14865 case value_t::binary:
14866 return write_bson_binary(name, *j.m_value.binary);
14867
14868 case value_t::boolean:
14869 return write_bson_boolean(name, j.m_value.boolean);
14870
14871 case value_t::number_float:
14872 return write_bson_double(name, j.m_value.number_float);
14873
14874 case value_t::number_integer:
14875 return write_bson_integer(name, j.m_value.number_integer);
14876
14877 case value_t::number_unsigned:
14878 return write_bson_unsigned(name, j);
14879
14880 case value_t::string:
14881 return write_bson_string(name, *j.m_value.string);
14882
14883 case value_t::null:
14884 return write_bson_null(name);
14885
14886 // LCOV_EXCL_START
14887 case value_t::discarded:
14888 default:
14889 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14890 return;
14891 // LCOV_EXCL_STOP
14892 }
14893 }
14894
14901 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14902 {
14903 std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
14904 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
14905 {
14906 return result += calc_bson_element_size(el.first, el.second);
14907 });
14908
14909 return sizeof(std::int32_t) + document_size + 1ul;
14910 }
14911
14916 void write_bson_object(const typename BasicJsonType::object_t& value)
14917 {
14918 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
14919
14920 for (const auto& el : value)
14921 {
14922 write_bson_element(el.first, el.second);
14923 }
14924
14925 oa->write_character(to_char_type(0x00));
14926 }
14927
14929 // CBOR //
14931
14932 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14933 {
14934 return to_char_type(0xFA); // Single-Precision Float
14935 }
14936
14937 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14938 {
14939 return to_char_type(0xFB); // Double-Precision Float
14940 }
14941
14943 // MsgPack //
14945
14946 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14947 {
14948 return to_char_type(0xCA); // float 32
14949 }
14950
14951 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14952 {
14953 return to_char_type(0xCB); // float 64
14954 }
14955
14957 // UBJSON //
14959
14960 // UBJSON: write number (floating point)
14961 template<typename NumberType, typename std::enable_if<
14962 std::is_floating_point<NumberType>::value, int>::type = 0>
14963 void write_number_with_ubjson_prefix(const NumberType n,
14964 const bool add_prefix)
14965 {
14966 if (add_prefix)
14967 {
14968 oa->write_character(get_ubjson_float_prefix(n));
14969 }
14970 write_number(n);
14971 }
14972
14973 // UBJSON: write number (unsigned integer)
14974 template<typename NumberType, typename std::enable_if<
14975 std::is_unsigned<NumberType>::value, int>::type = 0>
14976 void write_number_with_ubjson_prefix(const NumberType n,
14977 const bool add_prefix)
14978 {
14979 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14980 {
14981 if (add_prefix)
14982 {
14983 oa->write_character(to_char_type('i')); // int8
14984 }
14985 write_number(static_cast<std::uint8_t>(n));
14986 }
14987 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14988 {
14989 if (add_prefix)
14990 {
14991 oa->write_character(to_char_type('U')); // uint8
14992 }
14993 write_number(static_cast<std::uint8_t>(n));
14994 }
14995 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14996 {
14997 if (add_prefix)
14998 {
14999 oa->write_character(to_char_type('I')); // int16
15000 }
15001 write_number(static_cast<std::int16_t>(n));
15002 }
15003 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15004 {
15005 if (add_prefix)
15006 {
15007 oa->write_character(to_char_type('l')); // int32
15008 }
15009 write_number(static_cast<std::int32_t>(n));
15010 }
15011 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15012 {
15013 if (add_prefix)
15014 {
15015 oa->write_character(to_char_type('L')); // int64
15016 }
15017 write_number(static_cast<std::int64_t>(n));
15018 }
15019 else
15020 {
15021 if (add_prefix)
15022 {
15023 oa->write_character(to_char_type('H')); // high-precision number
15024 }
15025
15026 const auto number = BasicJsonType(n).dump();
15027 write_number_with_ubjson_prefix(number.size(), true);
15028 for (std::size_t i = 0; i < number.size(); ++i)
15029 {
15030 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15031 }
15032 }
15033 }
15034
15035 // UBJSON: write number (signed integer)
15036 template < typename NumberType, typename std::enable_if <
15037 std::is_signed<NumberType>::value&&
15038 !std::is_floating_point<NumberType>::value, int >::type = 0 >
15039 void write_number_with_ubjson_prefix(const NumberType n,
15040 const bool add_prefix)
15041 {
15042 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
15043 {
15044 if (add_prefix)
15045 {
15046 oa->write_character(to_char_type('i')); // int8
15047 }
15048 write_number(static_cast<std::int8_t>(n));
15049 }
15050 else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
15051 {
15052 if (add_prefix)
15053 {
15054 oa->write_character(to_char_type('U')); // uint8
15055 }
15056 write_number(static_cast<std::uint8_t>(n));
15057 }
15058 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
15059 {
15060 if (add_prefix)
15061 {
15062 oa->write_character(to_char_type('I')); // int16
15063 }
15064 write_number(static_cast<std::int16_t>(n));
15065 }
15066 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
15067 {
15068 if (add_prefix)
15069 {
15070 oa->write_character(to_char_type('l')); // int32
15071 }
15072 write_number(static_cast<std::int32_t>(n));
15073 }
15074 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
15075 {
15076 if (add_prefix)
15077 {
15078 oa->write_character(to_char_type('L')); // int64
15079 }
15080 write_number(static_cast<std::int64_t>(n));
15081 }
15082 // LCOV_EXCL_START
15083 else
15084 {
15085 if (add_prefix)
15086 {
15087 oa->write_character(to_char_type('H')); // high-precision number
15088 }
15089
15090 const auto number = BasicJsonType(n).dump();
15091 write_number_with_ubjson_prefix(number.size(), true);
15092 for (std::size_t i = 0; i < number.size(); ++i)
15093 {
15094 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15095 }
15096 }
15097 // LCOV_EXCL_STOP
15098 }
15099
15103 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
15104 {
15105 switch (j.type())
15106 {
15107 case value_t::null:
15108 return 'Z';
15109
15110 case value_t::boolean:
15111 return j.m_value.boolean ? 'T' : 'F';
15112
15113 case value_t::number_integer:
15114 {
15115 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15116 {
15117 return 'i';
15118 }
15119 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15120 {
15121 return 'U';
15122 }
15123 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15124 {
15125 return 'I';
15126 }
15127 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15128 {
15129 return 'l';
15130 }
15131 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15132 {
15133 return 'L';
15134 }
15135 // anything else is treated as high-precision number
15136 return 'H'; // LCOV_EXCL_LINE
15137 }
15138
15139 case value_t::number_unsigned:
15140 {
15141 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15142 {
15143 return 'i';
15144 }
15145 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
15146 {
15147 return 'U';
15148 }
15149 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15150 {
15151 return 'I';
15152 }
15153 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15154 {
15155 return 'l';
15156 }
15157 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15158 {
15159 return 'L';
15160 }
15161 // anything else is treated as high-precision number
15162 return 'H'; // LCOV_EXCL_LINE
15163 }
15164
15165 case value_t::number_float:
15166 return get_ubjson_float_prefix(j.m_value.number_float);
15167
15168 case value_t::string:
15169 return 'S';
15170
15171 case value_t::array: // fallthrough
15172 case value_t::binary:
15173 return '[';
15174
15175 case value_t::object:
15176 return '{';
15177
15178 case value_t::discarded:
15179 default: // discarded values
15180 return 'N';
15181 }
15182 }
15183
15184 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
15185 {
15186 return 'd'; // float 32
15187 }
15188
15189 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
15190 {
15191 return 'D'; // float 64
15192 }
15193
15195 // Utility functions //
15197
15198 /*
15199 @brief write a number to output input
15200 @param[in] n number of type @a NumberType
15201 @tparam NumberType the type of the number
15202 @tparam OutputIsLittleEndian Set to true if output data is
15203 required to be little endian
15204
15205 @note This function needs to respect the system's endianness, because bytes
15206 in CBOR, MessagePack, and UBJSON are stored in network order (big
15207 endian) and therefore need reordering on little endian systems.
15208 */
15209 template<typename NumberType, bool OutputIsLittleEndian = false>
15210 void write_number(const NumberType n)
15211 {
15212 // step 1: write number to array of length NumberType
15213 std::array<CharType, sizeof(NumberType)> vec{};
15214 std::memcpy(vec.data(), &n, sizeof(NumberType));
15215
15216 // step 2: write array to output (with possible reordering)
15217 if (is_little_endian != OutputIsLittleEndian)
15218 {
15219 // reverse byte order prior to conversion if necessary
15220 std::reverse(vec.begin(), vec.end());
15221 }
15222
15223 oa->write_characters(vec.data(), sizeof(NumberType));
15224 }
15225
15227 {
15228#ifdef __GNUC__
15229#pragma GCC diagnostic push
15230#pragma GCC diagnostic ignored "-Wfloat-equal"
15231#endif
15232 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
15233 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
15234 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
15235 {
15236 oa->write_character(format == detail::input_format_t::cbor
15237 ? get_cbor_float_prefix(static_cast<float>(n))
15238 : get_msgpack_float_prefix(static_cast<float>(n)));
15239 write_number(static_cast<float>(n));
15240 }
15241 else
15242 {
15243 oa->write_character(format == detail::input_format_t::cbor
15244 ? get_cbor_float_prefix(n)
15245 : get_msgpack_float_prefix(n));
15246 write_number(n);
15247 }
15248#ifdef __GNUC__
15249#pragma GCC diagnostic pop
15250#endif
15251 }
15252
15253 public:
15254 // The following to_char_type functions are implement the conversion
15255 // between uint8_t and CharType. In case CharType is not unsigned,
15256 // such a conversion is required to allow values greater than 128.
15257 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
15258 template < typename C = CharType,
15259 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
15260 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15261 {
15262 return *reinterpret_cast<char*>(&x);
15263 }
15264
15265 template < typename C = CharType,
15266 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
15267 static CharType to_char_type(std::uint8_t x) noexcept
15268 {
15269 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
15270 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
15271 CharType result;
15272 std::memcpy(&result, &x, sizeof(x));
15273 return result;
15274 }
15275
15276 template<typename C = CharType,
15278 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15279 {
15280 return x;
15281 }
15282
15283 template < typename InputCharType, typename C = CharType,
15284 enable_if_t <
15285 std::is_signed<C>::value &&
15286 std::is_signed<char>::value &&
15287 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
15288 > * = nullptr >
15289 static constexpr CharType to_char_type(InputCharType x) noexcept
15290 {
15291 return x;
15292 }
15293
15294 private:
15296 const bool is_little_endian = little_endianness();
15297
15300};
15301} // namespace detail
15302} // namespace nlohmann
15303
15304// #include <nlohmann/detail/output/output_adapters.hpp>
15305
15306// #include <nlohmann/detail/output/serializer.hpp>
15307
15308
15309#include <algorithm> // reverse, remove, fill, find, none_of
15310#include <array> // array
15311#include <clocale> // localeconv, lconv
15312#include <cmath> // labs, isfinite, isnan, signbit
15313#include <cstddef> // size_t, ptrdiff_t
15314#include <cstdint> // uint8_t
15315#include <cstdio> // snprintf
15316#include <limits> // numeric_limits
15317#include <string> // string, char_traits
15318#include <iomanip> // setfill, setw
15319#include <sstream> // stringstream
15320#include <type_traits> // is_same
15321#include <utility> // move
15322
15323// #include <nlohmann/detail/conversions/to_chars.hpp>
15324
15325
15326#include <array> // array
15327#include <cmath> // signbit, isfinite
15328#include <cstdint> // intN_t, uintN_t
15329#include <cstring> // memcpy, memmove
15330#include <limits> // numeric_limits
15331#include <type_traits> // conditional
15332
15333// #include <nlohmann/detail/macro_scope.hpp>
15334
15335
15336namespace nlohmann
15337{
15338namespace detail
15339{
15340
15360namespace dtoa_impl
15361{
15362
15363template<typename Target, typename Source>
15364Target reinterpret_bits(const Source source)
15365{
15366 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
15367
15368 Target target;
15369 std::memcpy(&target, &source, sizeof(Source));
15370 return target;
15371}
15372
15373struct diyfp // f * 2^e
15374{
15375 static constexpr int kPrecision = 64; // = q
15376
15377 std::uint64_t f = 0;
15378 int e = 0;
15379
15380 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
15381
15386 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
15387 {
15388 JSON_ASSERT(x.e == y.e);
15389 JSON_ASSERT(x.f >= y.f);
15390
15391 return {x.f - y.f, x.e};
15392 }
15393
15398 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
15399 {
15400 static_assert(kPrecision == 64, "internal error");
15401
15402 // Computes:
15403 // f = round((x.f * y.f) / 2^q)
15404 // e = x.e + y.e + q
15405
15406 // Emulate the 64-bit * 64-bit multiplication:
15407 //
15408 // p = u * v
15409 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
15410 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
15411 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
15412 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
15413 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
15414 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
15415 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
15416 //
15417 // (Since Q might be larger than 2^32 - 1)
15418 //
15419 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
15420 //
15421 // (Q_hi + H does not overflow a 64-bit int)
15422 //
15423 // = p_lo + 2^64 p_hi
15424
15425 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15426 const std::uint64_t u_hi = x.f >> 32u;
15427 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15428 const std::uint64_t v_hi = y.f >> 32u;
15429
15430 const std::uint64_t p0 = u_lo * v_lo;
15431 const std::uint64_t p1 = u_lo * v_hi;
15432 const std::uint64_t p2 = u_hi * v_lo;
15433 const std::uint64_t p3 = u_hi * v_hi;
15434
15435 const std::uint64_t p0_hi = p0 >> 32u;
15436 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15437 const std::uint64_t p1_hi = p1 >> 32u;
15438 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15439 const std::uint64_t p2_hi = p2 >> 32u;
15440
15441 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15442
15443 // The full product might now be computed as
15444 //
15445 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
15446 // p_lo = p0_lo + (Q << 32)
15447 //
15448 // But in this particular case here, the full p_lo is not required.
15449 // Effectively we only need to add the highest bit in p_lo to p_hi (and
15450 // Q_hi + 1 does not overflow).
15451
15452 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
15453
15454 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
15455
15456 return {h, x.e + y.e + 64};
15457 }
15458
15463 static diyfp normalize(diyfp x) noexcept
15464 {
15465 JSON_ASSERT(x.f != 0);
15466
15467 while ((x.f >> 63u) == 0)
15468 {
15469 x.f <<= 1u;
15470 x.e--;
15471 }
15472
15473 return x;
15474 }
15475
15480 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
15481 {
15482 const int delta = x.e - target_exponent;
15483
15484 JSON_ASSERT(delta >= 0);
15485 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
15486
15487 return {x.f << delta, target_exponent};
15488 }
15489};
15490
15492{
15496};
15497
15504template<typename FloatType>
15506{
15507 JSON_ASSERT(std::isfinite(value));
15508 JSON_ASSERT(value > 0);
15509
15510 // Convert the IEEE representation into a diyfp.
15511 //
15512 // If v is denormal:
15513 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
15514 // If v is normalized:
15515 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
15516
15517 static_assert(std::numeric_limits<FloatType>::is_iec559,
15518 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
15519
15520 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
15521 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
15522 constexpr int kMinExp = 1 - kBias;
15523 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
15524
15525 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
15526
15527 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
15528 const std::uint64_t E = bits >> (kPrecision - 1);
15529 const std::uint64_t F = bits & (kHiddenBit - 1);
15530
15531 const bool is_denormal = E == 0;
15532 const diyfp v = is_denormal
15533 ? diyfp(F, kMinExp)
15534 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
15535
15536 // Compute the boundaries m- and m+ of the floating-point value
15537 // v = f * 2^e.
15538 //
15539 // Determine v- and v+, the floating-point predecessor and successor if v,
15540 // respectively.
15541 //
15542 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
15543 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
15544 //
15545 // v+ = v + 2^e
15546 //
15547 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
15548 // between m- and m+ round to v, regardless of how the input rounding
15549 // algorithm breaks ties.
15550 //
15551 // ---+-------------+-------------+-------------+-------------+--- (A)
15552 // v- m- v m+ v+
15553 //
15554 // -----------------+------+------+-------------+-------------+--- (B)
15555 // v- m- v m+ v+
15556
15557 const bool lower_boundary_is_closer = F == 0 && E > 1;
15558 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
15559 const diyfp m_minus = lower_boundary_is_closer
15560 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
15561 : diyfp(2 * v.f - 1, v.e - 1); // (A)
15562
15563 // Determine the normalized w+ = m+.
15564 const diyfp w_plus = diyfp::normalize(m_plus);
15565
15566 // Determine w- = m- such that e_(w-) = e_(w+).
15567 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
15568
15569 return {diyfp::normalize(v), w_minus, w_plus};
15570}
15571
15572// Given normalized diyfp w, Grisu needs to find a (normalized) cached
15573// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
15574// within a certain range [alpha, gamma] (Definition 3.2 from [1])
15575//
15576// alpha <= e = e_c + e_w + q <= gamma
15577//
15578// or
15579//
15580// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
15581// <= f_c * f_w * 2^gamma
15582//
15583// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
15584//
15585// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
15586//
15587// or
15588//
15589// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
15590//
15591// The choice of (alpha,gamma) determines the size of the table and the form of
15592// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
15593// in practice:
15594//
15595// The idea is to cut the number c * w = f * 2^e into two parts, which can be
15596// processed independently: An integral part p1, and a fractional part p2:
15597//
15598// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
15599// = (f div 2^-e) + (f mod 2^-e) * 2^e
15600// = p1 + p2 * 2^e
15601//
15602// The conversion of p1 into decimal form requires a series of divisions and
15603// modulos by (a power of) 10. These operations are faster for 32-bit than for
15604// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
15605// achieved by choosing
15606//
15607// -e >= 32 or e <= -32 := gamma
15608//
15609// In order to convert the fractional part
15610//
15611// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
15612//
15613// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
15614// d[-i] are extracted in order:
15615//
15616// (10 * p2) div 2^-e = d[-1]
15617// (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
15618//
15619// The multiplication by 10 must not overflow. It is sufficient to choose
15620//
15621// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
15622//
15623// Since p2 = f mod 2^-e < 2^-e,
15624//
15625// -e <= 60 or e >= -60 := alpha
15626
15627constexpr int kAlpha = -60;
15628constexpr int kGamma = -32;
15629
15630struct cached_power // c = f * 2^e ~= 10^k
15631{
15632 std::uint64_t f;
15633 int e;
15634 int k;
15635};
15636
15645{
15646 // Now
15647 //
15648 // alpha <= e_c + e + q <= gamma (1)
15649 // ==> f_c * 2^alpha <= c * 2^e * 2^q
15650 //
15651 // and since the c's are normalized, 2^(q-1) <= f_c,
15652 //
15653 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
15654 // ==> 2^(alpha - e - 1) <= c
15655 //
15656 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
15657 //
15658 // k = ceil( log_10( 2^(alpha - e - 1) ) )
15659 // = ceil( (alpha - e - 1) * log_10(2) )
15660 //
15661 // From the paper:
15662 // "In theory the result of the procedure could be wrong since c is rounded,
15663 // and the computation itself is approximated [...]. In practice, however,
15664 // this simple function is sufficient."
15665 //
15666 // For IEEE double precision floating-point numbers converted into
15667 // normalized diyfp's w = f * 2^e, with q = 64,
15668 //
15669 // e >= -1022 (min IEEE exponent)
15670 // -52 (p - 1)
15671 // -52 (p - 1, possibly normalize denormal IEEE numbers)
15672 // -11 (normalize the diyfp)
15673 // = -1137
15674 //
15675 // and
15676 //
15677 // e <= +1023 (max IEEE exponent)
15678 // -52 (p - 1)
15679 // -11 (normalize the diyfp)
15680 // = 960
15681 //
15682 // This binary exponent range [-1137,960] results in a decimal exponent
15683 // range [-307,324]. One does not need to store a cached power for each
15684 // k in this range. For each such k it suffices to find a cached power
15685 // such that the exponent of the product lies in [alpha,gamma].
15686 // This implies that the difference of the decimal exponents of adjacent
15687 // table entries must be less than or equal to
15688 //
15689 // floor( (gamma - alpha) * log_10(2) ) = 8.
15690 //
15691 // (A smaller distance gamma-alpha would require a larger table.)
15692
15693 // NB:
15694 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
15695
15696 constexpr int kCachedPowersMinDecExp = -300;
15697 constexpr int kCachedPowersDecStep = 8;
15698
15699 static constexpr std::array<cached_power, 79> kCachedPowers =
15700 {
15701 {
15702 { 0xAB70FE17C79AC6CA, -1060, -300 },
15703 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
15704 { 0xBE5691EF416BD60C, -1007, -284 },
15705 { 0x8DD01FAD907FFC3C, -980, -276 },
15706 { 0xD3515C2831559A83, -954, -268 },
15707 { 0x9D71AC8FADA6C9B5, -927, -260 },
15708 { 0xEA9C227723EE8BCB, -901, -252 },
15709 { 0xAECC49914078536D, -874, -244 },
15710 { 0x823C12795DB6CE57, -847, -236 },
15711 { 0xC21094364DFB5637, -821, -228 },
15712 { 0x9096EA6F3848984F, -794, -220 },
15713 { 0xD77485CB25823AC7, -768, -212 },
15714 { 0xA086CFCD97BF97F4, -741, -204 },
15715 { 0xEF340A98172AACE5, -715, -196 },
15716 { 0xB23867FB2A35B28E, -688, -188 },
15717 { 0x84C8D4DFD2C63F3B, -661, -180 },
15718 { 0xC5DD44271AD3CDBA, -635, -172 },
15719 { 0x936B9FCEBB25C996, -608, -164 },
15720 { 0xDBAC6C247D62A584, -582, -156 },
15721 { 0xA3AB66580D5FDAF6, -555, -148 },
15722 { 0xF3E2F893DEC3F126, -529, -140 },
15723 { 0xB5B5ADA8AAFF80B8, -502, -132 },
15724 { 0x87625F056C7C4A8B, -475, -124 },
15725 { 0xC9BCFF6034C13053, -449, -116 },
15726 { 0x964E858C91BA2655, -422, -108 },
15727 { 0xDFF9772470297EBD, -396, -100 },
15728 { 0xA6DFBD9FB8E5B88F, -369, -92 },
15729 { 0xF8A95FCF88747D94, -343, -84 },
15730 { 0xB94470938FA89BCF, -316, -76 },
15731 { 0x8A08F0F8BF0F156B, -289, -68 },
15732 { 0xCDB02555653131B6, -263, -60 },
15733 { 0x993FE2C6D07B7FAC, -236, -52 },
15734 { 0xE45C10C42A2B3B06, -210, -44 },
15735 { 0xAA242499697392D3, -183, -36 },
15736 { 0xFD87B5F28300CA0E, -157, -28 },
15737 { 0xBCE5086492111AEB, -130, -20 },
15738 { 0x8CBCCC096F5088CC, -103, -12 },
15739 { 0xD1B71758E219652C, -77, -4 },
15740 { 0x9C40000000000000, -50, 4 },
15741 { 0xE8D4A51000000000, -24, 12 },
15742 { 0xAD78EBC5AC620000, 3, 20 },
15743 { 0x813F3978F8940984, 30, 28 },
15744 { 0xC097CE7BC90715B3, 56, 36 },
15745 { 0x8F7E32CE7BEA5C70, 83, 44 },
15746 { 0xD5D238A4ABE98068, 109, 52 },
15747 { 0x9F4F2726179A2245, 136, 60 },
15748 { 0xED63A231D4C4FB27, 162, 68 },
15749 { 0xB0DE65388CC8ADA8, 189, 76 },
15750 { 0x83C7088E1AAB65DB, 216, 84 },
15751 { 0xC45D1DF942711D9A, 242, 92 },
15752 { 0x924D692CA61BE758, 269, 100 },
15753 { 0xDA01EE641A708DEA, 295, 108 },
15754 { 0xA26DA3999AEF774A, 322, 116 },
15755 { 0xF209787BB47D6B85, 348, 124 },
15756 { 0xB454E4A179DD1877, 375, 132 },
15757 { 0x865B86925B9BC5C2, 402, 140 },
15758 { 0xC83553C5C8965D3D, 428, 148 },
15759 { 0x952AB45CFA97A0B3, 455, 156 },
15760 { 0xDE469FBD99A05FE3, 481, 164 },
15761 { 0xA59BC234DB398C25, 508, 172 },
15762 { 0xF6C69A72A3989F5C, 534, 180 },
15763 { 0xB7DCBF5354E9BECE, 561, 188 },
15764 { 0x88FCF317F22241E2, 588, 196 },
15765 { 0xCC20CE9BD35C78A5, 614, 204 },
15766 { 0x98165AF37B2153DF, 641, 212 },
15767 { 0xE2A0B5DC971F303A, 667, 220 },
15768 { 0xA8D9D1535CE3B396, 694, 228 },
15769 { 0xFB9B7CD9A4A7443C, 720, 236 },
15770 { 0xBB764C4CA7A44410, 747, 244 },
15771 { 0x8BAB8EEFB6409C1A, 774, 252 },
15772 { 0xD01FEF10A657842C, 800, 260 },
15773 { 0x9B10A4E5E9913129, 827, 268 },
15774 { 0xE7109BFBA19C0C9D, 853, 276 },
15775 { 0xAC2820D9623BF429, 880, 284 },
15776 { 0x80444B5E7AA7CF85, 907, 292 },
15777 { 0xBF21E44003ACDD2D, 933, 300 },
15778 { 0x8E679C2F5E44FF8F, 960, 308 },
15779 { 0xD433179D9C8CB841, 986, 316 },
15780 { 0x9E19DB92B4E31BA9, 1013, 324 },
15781 }
15782 };
15783
15784 // This computation gives exactly the same results for k as
15785 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
15786 // for |e| <= 1500, but doesn't require floating-point operations.
15787 // NB: log_10(2) ~= 78913 / 2^18
15788 JSON_ASSERT(e >= -1500);
15789 JSON_ASSERT(e <= 1500);
15790 const int f = kAlpha - e - 1;
15791 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
15792
15793 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
15794 JSON_ASSERT(index >= 0);
15795 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
15796
15797 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
15798 JSON_ASSERT(kAlpha <= cached.e + e + 64);
15799 JSON_ASSERT(kGamma >= cached.e + e + 64);
15800
15801 return cached;
15802}
15803
15808inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
15809{
15810 // LCOV_EXCL_START
15811 if (n >= 1000000000)
15812 {
15813 pow10 = 1000000000;
15814 return 10;
15815 }
15816 // LCOV_EXCL_STOP
15817 if (n >= 100000000)
15818 {
15819 pow10 = 100000000;
15820 return 9;
15821 }
15822 if (n >= 10000000)
15823 {
15824 pow10 = 10000000;
15825 return 8;
15826 }
15827 if (n >= 1000000)
15828 {
15829 pow10 = 1000000;
15830 return 7;
15831 }
15832 if (n >= 100000)
15833 {
15834 pow10 = 100000;
15835 return 6;
15836 }
15837 if (n >= 10000)
15838 {
15839 pow10 = 10000;
15840 return 5;
15841 }
15842 if (n >= 1000)
15843 {
15844 pow10 = 1000;
15845 return 4;
15846 }
15847 if (n >= 100)
15848 {
15849 pow10 = 100;
15850 return 3;
15851 }
15852 if (n >= 10)
15853 {
15854 pow10 = 10;
15855 return 2;
15856 }
15857
15858 pow10 = 1;
15859 return 1;
15860}
15861
15862inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
15863 std::uint64_t rest, std::uint64_t ten_k)
15864{
15865 JSON_ASSERT(len >= 1);
15866 JSON_ASSERT(dist <= delta);
15867 JSON_ASSERT(rest <= delta);
15868 JSON_ASSERT(ten_k > 0);
15869
15870 // <--------------------------- delta ---->
15871 // <---- dist --------->
15872 // --------------[------------------+-------------------]--------------
15873 // M- w M+
15874 //
15875 // ten_k
15876 // <------>
15877 // <---- rest ---->
15878 // --------------[------------------+----+--------------]--------------
15879 // w V
15880 // = buf * 10^k
15881 //
15882 // ten_k represents a unit-in-the-last-place in the decimal representation
15883 // stored in buf.
15884 // Decrement buf by ten_k while this takes buf closer to w.
15885
15886 // The tests are written in this order to avoid overflow in unsigned
15887 // integer arithmetic.
15888
15889 while (rest < dist
15890 && delta - rest >= ten_k
15891 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
15892 {
15893 JSON_ASSERT(buf[len - 1] != '0');
15894 buf[len - 1]--;
15895 rest += ten_k;
15896 }
15897}
15898
15903inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
15904 diyfp M_minus, diyfp w, diyfp M_plus)
15905{
15906 static_assert(kAlpha >= -60, "internal error");
15907 static_assert(kGamma <= -32, "internal error");
15908
15909 // Generates the digits (and the exponent) of a decimal floating-point
15910 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15911 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15912 //
15913 // <--------------------------- delta ---->
15914 // <---- dist --------->
15915 // --------------[------------------+-------------------]--------------
15916 // M- w M+
15917 //
15918 // Grisu2 generates the digits of M+ from left to right and stops as soon as
15919 // V is in [M-,M+].
15920
15921 JSON_ASSERT(M_plus.e >= kAlpha);
15922 JSON_ASSERT(M_plus.e <= kGamma);
15923
15924 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15925 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
15926
15927 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15928 //
15929 // M+ = f * 2^e
15930 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15931 // = ((p1 ) * 2^-e + (p2 )) * 2^e
15932 // = p1 + p2 * 2^e
15933
15934 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
15935
15936 auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
15937 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
15938
15939 // 1)
15940 //
15941 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15942
15943 JSON_ASSERT(p1 > 0);
15944
15945 std::uint32_t pow10{};
15946 const int k = find_largest_pow10(p1, pow10);
15947
15948 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15949 //
15950 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15951 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
15952 //
15953 // M+ = p1 + p2 * 2^e
15954 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
15955 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15956 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
15957 //
15958 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15959 //
15960 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15961 //
15962 // but stop as soon as
15963 //
15964 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15965
15966 int n = k;
15967 while (n > 0)
15968 {
15969 // Invariants:
15970 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
15971 // pow10 = 10^(n-1) <= p1 < 10^n
15972 //
15973 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
15974 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
15975 //
15976 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15977 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15978 //
15979 JSON_ASSERT(d <= 9);
15980 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15981 //
15982 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15983 //
15984 p1 = r;
15985 n--;
15986 //
15987 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
15988 // pow10 = 10^n
15989 //
15990
15991 // Now check if enough digits have been generated.
15992 // Compute
15993 //
15994 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15995 //
15996 // Note:
15997 // Since rest and delta share the same exponent e, it suffices to
15998 // compare the significands.
15999 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
16000 if (rest <= delta)
16001 {
16002 // V = buffer * 10^n, with M- <= V <= M+.
16003
16004 decimal_exponent += n;
16005
16006 // We may now just stop. But instead look if the buffer could be
16007 // decremented to bring V closer to w.
16008 //
16009 // pow10 = 10^n is now 1 ulp in the decimal representation V.
16010 // The rounding procedure works with diyfp's with an implicit
16011 // exponent of e.
16012 //
16013 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
16014 //
16015 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
16016 grisu2_round(buffer, length, dist, delta, rest, ten_n);
16017
16018 return;
16019 }
16020
16021 pow10 /= 10;
16022 //
16023 // pow10 = 10^(n-1) <= p1 < 10^n
16024 // Invariants restored.
16025 }
16026
16027 // 2)
16028 //
16029 // The digits of the integral part have been generated:
16030 //
16031 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
16032 // = buffer + p2 * 2^e
16033 //
16034 // Now generate the digits of the fractional part p2 * 2^e.
16035 //
16036 // Note:
16037 // No decimal point is generated: the exponent is adjusted instead.
16038 //
16039 // p2 actually represents the fraction
16040 //
16041 // p2 * 2^e
16042 // = p2 / 2^-e
16043 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
16044 //
16045 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
16046 //
16047 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
16048 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
16049 //
16050 // using
16051 //
16052 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
16053 // = ( d) * 2^-e + ( r)
16054 //
16055 // or
16056 // 10^m * p2 * 2^e = d + r * 2^e
16057 //
16058 // i.e.
16059 //
16060 // M+ = buffer + p2 * 2^e
16061 // = buffer + 10^-m * (d + r * 2^e)
16062 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
16063 //
16064 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
16065
16066 JSON_ASSERT(p2 > delta);
16067
16068 int m = 0;
16069 for (;;)
16070 {
16071 // Invariant:
16072 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
16073 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
16074 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
16075 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
16076 //
16077 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
16078 p2 *= 10;
16079 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
16080 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
16081 //
16082 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
16083 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
16084 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
16085 //
16086 JSON_ASSERT(d <= 9);
16087 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
16088 //
16089 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
16090 //
16091 p2 = r;
16092 m++;
16093 //
16094 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
16095 // Invariant restored.
16096
16097 // Check if enough digits have been generated.
16098 //
16099 // 10^-m * p2 * 2^e <= delta * 2^e
16100 // p2 * 2^e <= 10^m * delta * 2^e
16101 // p2 <= 10^m * delta
16102 delta *= 10;
16103 dist *= 10;
16104 if (p2 <= delta)
16105 {
16106 break;
16107 }
16108 }
16109
16110 // V = buffer * 10^-m, with M- <= V <= M+.
16111
16112 decimal_exponent -= m;
16113
16114 // 1 ulp in the decimal representation is now 10^-m.
16115 // Since delta and dist are now scaled by 10^m, we need to do the
16116 // same with ulp in order to keep the units in sync.
16117 //
16118 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
16119 //
16120 const std::uint64_t ten_m = one.f;
16121 grisu2_round(buffer, length, dist, delta, p2, ten_m);
16122
16123 // By construction this algorithm generates the shortest possible decimal
16124 // number (Loitsch, Theorem 6.2) which rounds back to w.
16125 // For an input number of precision p, at least
16126 //
16127 // N = 1 + ceil(p * log_10(2))
16128 //
16129 // decimal digits are sufficient to identify all binary floating-point
16130 // numbers (Matula, "In-and-Out conversions").
16131 // This implies that the algorithm does not produce more than N decimal
16132 // digits.
16133 //
16134 // N = 17 for p = 53 (IEEE double precision)
16135 // N = 9 for p = 24 (IEEE single precision)
16136}
16137
16144inline void grisu2(char* buf, int& len, int& decimal_exponent,
16145 diyfp m_minus, diyfp v, diyfp m_plus)
16146{
16147 JSON_ASSERT(m_plus.e == m_minus.e);
16148 JSON_ASSERT(m_plus.e == v.e);
16149
16150 // --------(-----------------------+-----------------------)-------- (A)
16151 // m- v m+
16152 //
16153 // --------------------(-----------+-----------------------)-------- (B)
16154 // m- v m+
16155 //
16156 // First scale v (and m- and m+) such that the exponent is in the range
16157 // [alpha, gamma].
16158
16159 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
16160
16161 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
16162
16163 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
16164 const diyfp w = diyfp::mul(v, c_minus_k);
16165 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
16166 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
16167
16168 // ----(---+---)---------------(---+---)---------------(---+---)----
16169 // w- w w+
16170 // = c*m- = c*v = c*m+
16171 //
16172 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
16173 // w+ are now off by a small amount.
16174 // In fact:
16175 //
16176 // w - v * 10^k < 1 ulp
16177 //
16178 // To account for this inaccuracy, add resp. subtract 1 ulp.
16179 //
16180 // --------+---[---------------(---+---)---------------]---+--------
16181 // w- M- w M+ w+
16182 //
16183 // Now any number in [M-, M+] (bounds included) will round to w when input,
16184 // regardless of how the input rounding algorithm breaks ties.
16185 //
16186 // And digit_gen generates the shortest possible such number in [M-, M+].
16187 // Note that this does not mean that Grisu2 always generates the shortest
16188 // possible number in the interval (m-, m+).
16189 const diyfp M_minus(w_minus.f + 1, w_minus.e);
16190 const diyfp M_plus (w_plus.f - 1, w_plus.e );
16191
16192 decimal_exponent = -cached.k; // = -(-k) = k
16193
16194 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
16195}
16196
16202template<typename FloatType>
16204void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
16205{
16206 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
16207 "internal error: not enough precision");
16208
16209 JSON_ASSERT(std::isfinite(value));
16210 JSON_ASSERT(value > 0);
16211
16212 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
16213 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
16214 // decimal representations are not exactly "short".
16215 //
16216 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
16217 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
16218 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
16219 // does.
16220 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
16221 // representation using the corresponding std::from_chars function recovers value exactly". That
16222 // indicates that single precision floating-point numbers should be recovered using
16223 // 'std::strtof'.
16224 //
16225 // NB: If the neighbors are computed for single-precision numbers, there is a single float
16226 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
16227 // value is off by 1 ulp.
16228#if 0
16229 const boundaries w = compute_boundaries(static_cast<double>(value));
16230#else
16232#endif
16233
16234 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
16235}
16236
16244inline char* append_exponent(char* buf, int e)
16245{
16246 JSON_ASSERT(e > -1000);
16247 JSON_ASSERT(e < 1000);
16248
16249 if (e < 0)
16250 {
16251 e = -e;
16252 *buf++ = '-';
16253 }
16254 else
16255 {
16256 *buf++ = '+';
16257 }
16258
16259 auto k = static_cast<std::uint32_t>(e);
16260 if (k < 10)
16261 {
16262 // Always print at least two digits in the exponent.
16263 // This is for compatibility with printf("%g").
16264 *buf++ = '0';
16265 *buf++ = static_cast<char>('0' + k);
16266 }
16267 else if (k < 100)
16268 {
16269 *buf++ = static_cast<char>('0' + k / 10);
16270 k %= 10;
16271 *buf++ = static_cast<char>('0' + k);
16272 }
16273 else
16274 {
16275 *buf++ = static_cast<char>('0' + k / 100);
16276 k %= 100;
16277 *buf++ = static_cast<char>('0' + k / 10);
16278 k %= 10;
16279 *buf++ = static_cast<char>('0' + k);
16280 }
16281
16282 return buf;
16283}
16284
16296inline char* format_buffer(char* buf, int len, int decimal_exponent,
16297 int min_exp, int max_exp)
16298{
16299 JSON_ASSERT(min_exp < 0);
16300 JSON_ASSERT(max_exp > 0);
16301
16302 const int k = len;
16303 const int n = len + decimal_exponent;
16304
16305 // v = buf * 10^(n-k)
16306 // k is the length of the buffer (number of decimal digits)
16307 // n is the position of the decimal point relative to the start of the buffer.
16308
16309 if (k <= n && n <= max_exp)
16310 {
16311 // digits[000]
16312 // len <= max_exp + 2
16313
16314 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
16315 // Make it look like a floating-point number (#362, #378)
16316 buf[n + 0] = '.';
16317 buf[n + 1] = '0';
16318 return buf + (static_cast<size_t>(n) + 2);
16319 }
16320
16321 if (0 < n && n <= max_exp)
16322 {
16323 // dig.its
16324 // len <= max_digits10 + 1
16325
16326 JSON_ASSERT(k > n);
16327
16328 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
16329 buf[n] = '.';
16330 return buf + (static_cast<size_t>(k) + 1U);
16331 }
16332
16333 if (min_exp < n && n <= 0)
16334 {
16335 // 0.[000]digits
16336 // len <= 2 + (-min_exp - 1) + max_digits10
16337
16338 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
16339 buf[0] = '0';
16340 buf[1] = '.';
16341 std::memset(buf + 2, '0', static_cast<size_t>(-n));
16342 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
16343 }
16344
16345 if (k == 1)
16346 {
16347 // dE+123
16348 // len <= 1 + 5
16349
16350 buf += 1;
16351 }
16352 else
16353 {
16354 // d.igitsE+123
16355 // len <= max_digits10 + 1 + 5
16356
16357 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
16358 buf[1] = '.';
16359 buf += 1 + static_cast<size_t>(k);
16360 }
16361
16362 *buf++ = 'e';
16363 return append_exponent(buf, n - 1);
16364}
16365
16366} // namespace dtoa_impl
16367
16378template<typename FloatType>
16381char* to_chars(char* first, const char* last, FloatType value)
16382{
16383 static_cast<void>(last); // maybe unused - fix warning
16384 JSON_ASSERT(std::isfinite(value));
16385
16386 // Use signbit(value) instead of (value < 0) since signbit works for -0.
16387 if (std::signbit(value))
16388 {
16389 value = -value;
16390 *first++ = '-';
16391 }
16392
16393#ifdef __GNUC__
16394#pragma GCC diagnostic push
16395#pragma GCC diagnostic ignored "-Wfloat-equal"
16396#endif
16397 if (value == 0) // +-0
16398 {
16399 *first++ = '0';
16400 // Make it look like a floating-point number (#362, #378)
16401 *first++ = '.';
16402 *first++ = '0';
16403 return first;
16404 }
16405#ifdef __GNUC__
16406#pragma GCC diagnostic pop
16407#endif
16408
16409 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
16410
16411 // Compute v = buffer * 10^decimal_exponent.
16412 // The decimal digits are stored in the buffer, which needs to be interpreted
16413 // as an unsigned decimal integer.
16414 // len is the length of the buffer, i.e. the number of decimal digits.
16415 int len = 0;
16416 int decimal_exponent = 0;
16417 dtoa_impl::grisu2(first, len, decimal_exponent, value);
16418
16419 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
16420
16421 // Format the buffer like printf("%.*g", prec, value)
16422 constexpr int kMinExp = -4;
16423 // Use digits10 here to increase compatibility with version 2.
16424 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
16425
16426 JSON_ASSERT(last - first >= kMaxExp + 2);
16427 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
16428 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
16429
16430 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
16431}
16432
16433} // namespace detail
16434} // namespace nlohmann
16435
16436// #include <nlohmann/detail/exceptions.hpp>
16437
16438// #include <nlohmann/detail/macro_scope.hpp>
16439
16440// #include <nlohmann/detail/meta/cpp_future.hpp>
16441
16442// #include <nlohmann/detail/output/binary_writer.hpp>
16443
16444// #include <nlohmann/detail/output/output_adapters.hpp>
16445
16446// #include <nlohmann/detail/value_t.hpp>
16447
16448
16449namespace nlohmann
16450{
16451namespace detail
16452{
16454// serialization //
16456
16459{
16460 strict,
16461 replace,
16462 ignore
16463};
16464
16465template<typename BasicJsonType>
16467{
16468 using string_t = typename BasicJsonType::string_t;
16469 using number_float_t = typename BasicJsonType::number_float_t;
16470 using number_integer_t = typename BasicJsonType::number_integer_t;
16471 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
16472 using binary_char_t = typename BasicJsonType::binary_t::value_type;
16473 static constexpr std::uint8_t UTF8_ACCEPT = 0;
16474 static constexpr std::uint8_t UTF8_REJECT = 1;
16475
16476 public:
16484 : o(std::move(s))
16485 , loc(std::localeconv())
16486 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
16487 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
16488 , indent_char(ichar)
16490 , error_handler(error_handler_)
16491 {}
16492
16493 // delete because of pointer members
16494 serializer(const serializer&) = delete;
16498 ~serializer() = default;
16499
16522 void dump(const BasicJsonType& val,
16523 const bool pretty_print,
16524 const bool ensure_ascii,
16525 const unsigned int indent_step,
16526 const unsigned int current_indent = 0)
16527 {
16528 switch (val.m_type)
16529 {
16530 case value_t::object:
16531 {
16532 if (val.m_value.object->empty())
16533 {
16534 o->write_characters("{}", 2);
16535 return;
16536 }
16537
16538 if (pretty_print)
16539 {
16540 o->write_characters("{\n", 2);
16541
16542 // variable to hold indentation for recursive calls
16543 const auto new_indent = current_indent + indent_step;
16544 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16545 {
16546 indent_string.resize(indent_string.size() * 2, ' ');
16547 }
16548
16549 // first n-1 elements
16550 auto i = val.m_value.object->cbegin();
16551 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16552 {
16553 o->write_characters(indent_string.c_str(), new_indent);
16554 o->write_character('\"');
16555 dump_escaped(i->first, ensure_ascii);
16556 o->write_characters("\": ", 3);
16557 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16558 o->write_characters(",\n", 2);
16559 }
16560
16561 // last element
16562 JSON_ASSERT(i != val.m_value.object->cend());
16563 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16564 o->write_characters(indent_string.c_str(), new_indent);
16565 o->write_character('\"');
16566 dump_escaped(i->first, ensure_ascii);
16567 o->write_characters("\": ", 3);
16568 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16569
16570 o->write_character('\n');
16571 o->write_characters(indent_string.c_str(), current_indent);
16572 o->write_character('}');
16573 }
16574 else
16575 {
16576 o->write_character('{');
16577
16578 // first n-1 elements
16579 auto i = val.m_value.object->cbegin();
16580 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16581 {
16582 o->write_character('\"');
16583 dump_escaped(i->first, ensure_ascii);
16584 o->write_characters("\":", 2);
16585 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16586 o->write_character(',');
16587 }
16588
16589 // last element
16590 JSON_ASSERT(i != val.m_value.object->cend());
16591 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16592 o->write_character('\"');
16593 dump_escaped(i->first, ensure_ascii);
16594 o->write_characters("\":", 2);
16595 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16596
16597 o->write_character('}');
16598 }
16599
16600 return;
16601 }
16602
16603 case value_t::array:
16604 {
16605 if (val.m_value.array->empty())
16606 {
16607 o->write_characters("[]", 2);
16608 return;
16609 }
16610
16611 if (pretty_print)
16612 {
16613 o->write_characters("[\n", 2);
16614
16615 // variable to hold indentation for recursive calls
16616 const auto new_indent = current_indent + indent_step;
16617 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16618 {
16619 indent_string.resize(indent_string.size() * 2, ' ');
16620 }
16621
16622 // first n-1 elements
16623 for (auto i = val.m_value.array->cbegin();
16624 i != val.m_value.array->cend() - 1; ++i)
16625 {
16626 o->write_characters(indent_string.c_str(), new_indent);
16627 dump(*i, true, ensure_ascii, indent_step, new_indent);
16628 o->write_characters(",\n", 2);
16629 }
16630
16631 // last element
16632 JSON_ASSERT(!val.m_value.array->empty());
16633 o->write_characters(indent_string.c_str(), new_indent);
16634 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
16635
16636 o->write_character('\n');
16637 o->write_characters(indent_string.c_str(), current_indent);
16638 o->write_character(']');
16639 }
16640 else
16641 {
16642 o->write_character('[');
16643
16644 // first n-1 elements
16645 for (auto i = val.m_value.array->cbegin();
16646 i != val.m_value.array->cend() - 1; ++i)
16647 {
16648 dump(*i, false, ensure_ascii, indent_step, current_indent);
16649 o->write_character(',');
16650 }
16651
16652 // last element
16653 JSON_ASSERT(!val.m_value.array->empty());
16654 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
16655
16656 o->write_character(']');
16657 }
16658
16659 return;
16660 }
16661
16662 case value_t::string:
16663 {
16664 o->write_character('\"');
16665 dump_escaped(*val.m_value.string, ensure_ascii);
16666 o->write_character('\"');
16667 return;
16668 }
16669
16670 case value_t::binary:
16671 {
16672 if (pretty_print)
16673 {
16674 o->write_characters("{\n", 2);
16675
16676 // variable to hold indentation for recursive calls
16677 const auto new_indent = current_indent + indent_step;
16678 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16679 {
16680 indent_string.resize(indent_string.size() * 2, ' ');
16681 }
16682
16683 o->write_characters(indent_string.c_str(), new_indent);
16684
16685 o->write_characters("\"bytes\": [", 10);
16686
16687 if (!val.m_value.binary->empty())
16688 {
16689 for (auto i = val.m_value.binary->cbegin();
16690 i != val.m_value.binary->cend() - 1; ++i)
16691 {
16692 dump_integer(*i);
16693 o->write_characters(", ", 2);
16694 }
16695 dump_integer(val.m_value.binary->back());
16696 }
16697
16698 o->write_characters("],\n", 3);
16699 o->write_characters(indent_string.c_str(), new_indent);
16700
16701 o->write_characters("\"subtype\": ", 11);
16702 if (val.m_value.binary->has_subtype())
16703 {
16704 dump_integer(val.m_value.binary->subtype());
16705 }
16706 else
16707 {
16708 o->write_characters("null", 4);
16709 }
16710 o->write_character('\n');
16711 o->write_characters(indent_string.c_str(), current_indent);
16712 o->write_character('}');
16713 }
16714 else
16715 {
16716 o->write_characters("{\"bytes\":[", 10);
16717
16718 if (!val.m_value.binary->empty())
16719 {
16720 for (auto i = val.m_value.binary->cbegin();
16721 i != val.m_value.binary->cend() - 1; ++i)
16722 {
16723 dump_integer(*i);
16724 o->write_character(',');
16725 }
16726 dump_integer(val.m_value.binary->back());
16727 }
16728
16729 o->write_characters("],\"subtype\":", 12);
16730 if (val.m_value.binary->has_subtype())
16731 {
16732 dump_integer(val.m_value.binary->subtype());
16733 o->write_character('}');
16734 }
16735 else
16736 {
16737 o->write_characters("null}", 5);
16738 }
16739 }
16740 return;
16741 }
16742
16743 case value_t::boolean:
16744 {
16745 if (val.m_value.boolean)
16746 {
16747 o->write_characters("true", 4);
16748 }
16749 else
16750 {
16751 o->write_characters("false", 5);
16752 }
16753 return;
16754 }
16755
16757 {
16758 dump_integer(val.m_value.number_integer);
16759 return;
16760 }
16761
16763 {
16764 dump_integer(val.m_value.number_unsigned);
16765 return;
16766 }
16767
16769 {
16770 dump_float(val.m_value.number_float);
16771 return;
16772 }
16773
16774 case value_t::discarded:
16775 {
16776 o->write_characters("<discarded>", 11);
16777 return;
16778 }
16779
16780 case value_t::null:
16781 {
16782 o->write_characters("null", 4);
16783 return;
16784 }
16785
16786 default: // LCOV_EXCL_LINE
16787 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16788 }
16789 }
16790
16806 void dump_escaped(const string_t& s, const bool ensure_ascii)
16807 {
16808 std::uint32_t codepoint{};
16809 std::uint8_t state = UTF8_ACCEPT;
16810 std::size_t bytes = 0; // number of bytes written to string_buffer
16811
16812 // number of bytes written at the point of the last valid byte
16814 std::size_t undumped_chars = 0;
16815
16816 for (std::size_t i = 0; i < s.size(); ++i)
16817 {
16818 const auto byte = static_cast<std::uint8_t>(s[i]);
16819
16820 switch (decode(state, codepoint, byte))
16821 {
16822 case UTF8_ACCEPT: // decode found a new code point
16823 {
16824 switch (codepoint)
16825 {
16826 case 0x08: // backspace
16827 {
16828 string_buffer[bytes++] = '\\';
16829 string_buffer[bytes++] = 'b';
16830 break;
16831 }
16832
16833 case 0x09: // horizontal tab
16834 {
16835 string_buffer[bytes++] = '\\';
16836 string_buffer[bytes++] = 't';
16837 break;
16838 }
16839
16840 case 0x0A: // newline
16841 {
16842 string_buffer[bytes++] = '\\';
16843 string_buffer[bytes++] = 'n';
16844 break;
16845 }
16846
16847 case 0x0C: // formfeed
16848 {
16849 string_buffer[bytes++] = '\\';
16850 string_buffer[bytes++] = 'f';
16851 break;
16852 }
16853
16854 case 0x0D: // carriage return
16855 {
16856 string_buffer[bytes++] = '\\';
16857 string_buffer[bytes++] = 'r';
16858 break;
16859 }
16860
16861 case 0x22: // quotation mark
16862 {
16863 string_buffer[bytes++] = '\\';
16864 string_buffer[bytes++] = '\"';
16865 break;
16866 }
16867
16868 case 0x5C: // reverse solidus
16869 {
16870 string_buffer[bytes++] = '\\';
16871 string_buffer[bytes++] = '\\';
16872 break;
16873 }
16874
16875 default:
16876 {
16877 // escape control characters (0x00..0x1F) or, if
16878 // ensure_ascii parameter is used, non-ASCII characters
16879 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
16880 {
16881 if (codepoint <= 0xFFFF)
16882 {
16883 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16884 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
16885 static_cast<std::uint16_t>(codepoint));
16886 bytes += 6;
16887 }
16888 else
16889 {
16890 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16891 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
16892 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
16893 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
16894 bytes += 12;
16895 }
16896 }
16897 else
16898 {
16899 // copy byte to buffer (all previous bytes
16900 // been copied have in default case above)
16901 string_buffer[bytes++] = s[i];
16902 }
16903 break;
16904 }
16905 }
16906
16907 // write buffer and reset index; there must be 13 bytes
16908 // left, as this is the maximal number of bytes to be
16909 // written ("\uxxxx\uxxxx\0") for one code point
16910 if (string_buffer.size() - bytes < 13)
16911 {
16912 o->write_characters(string_buffer.data(), bytes);
16913 bytes = 0;
16914 }
16915
16916 // remember the byte position of this accept
16918 undumped_chars = 0;
16919 break;
16920 }
16921
16922 case UTF8_REJECT: // decode found invalid UTF-8 byte
16923 {
16924 switch (error_handler)
16925 {
16927 {
16928 std::stringstream ss;
16929 ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (byte | 0);
16930 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + ss.str(), BasicJsonType()));
16931 }
16932
16935 {
16936 // in case we saw this character the first time, we
16937 // would like to read it again, because the byte
16938 // may be OK for itself, but just not OK for the
16939 // previous sequence
16940 if (undumped_chars > 0)
16941 {
16942 --i;
16943 }
16944
16945 // reset length buffer to the last accepted index;
16946 // thus removing/ignoring the invalid characters
16948
16950 {
16951 // add a replacement character
16952 if (ensure_ascii)
16953 {
16954 string_buffer[bytes++] = '\\';
16955 string_buffer[bytes++] = 'u';
16956 string_buffer[bytes++] = 'f';
16957 string_buffer[bytes++] = 'f';
16958 string_buffer[bytes++] = 'f';
16959 string_buffer[bytes++] = 'd';
16960 }
16961 else
16962 {
16966 }
16967
16968 // write buffer and reset index; there must be 13 bytes
16969 // left, as this is the maximal number of bytes to be
16970 // written ("\uxxxx\uxxxx\0") for one code point
16971 if (string_buffer.size() - bytes < 13)
16972 {
16973 o->write_characters(string_buffer.data(), bytes);
16974 bytes = 0;
16975 }
16976
16978 }
16979
16980 undumped_chars = 0;
16981
16982 // continue processing the string
16984 break;
16985 }
16986
16987 default: // LCOV_EXCL_LINE
16988 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16989 }
16990 break;
16991 }
16992
16993 default: // decode found yet incomplete multi-byte code point
16994 {
16995 if (!ensure_ascii)
16996 {
16997 // code point will not be escaped - copy byte to buffer
16998 string_buffer[bytes++] = s[i];
16999 }
17001 break;
17002 }
17003 }
17004 }
17005
17006 // we finished processing the string
17008 {
17009 // write buffer
17010 if (bytes > 0)
17011 {
17012 o->write_characters(string_buffer.data(), bytes);
17013 }
17014 }
17015 else
17016 {
17017 // we finish reading, but do not accept: string was incomplete
17018 switch (error_handler)
17019 {
17021 {
17022 std::stringstream ss;
17023 ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (static_cast<std::uint8_t>(s.back()) | 0);
17024 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + ss.str(), BasicJsonType()));
17025 }
17026
17028 {
17029 // write all accepted bytes
17030 o->write_characters(string_buffer.data(), bytes_after_last_accept);
17031 break;
17032 }
17033
17035 {
17036 // write all accepted bytes
17037 o->write_characters(string_buffer.data(), bytes_after_last_accept);
17038 // add a replacement character
17039 if (ensure_ascii)
17040 {
17041 o->write_characters("\\ufffd", 6);
17042 }
17043 else
17044 {
17045 o->write_characters("\xEF\xBF\xBD", 3);
17046 }
17047 break;
17048 }
17049
17050 default: // LCOV_EXCL_LINE
17051 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17052 }
17053 }
17054 }
17055
17056 private:
17065 inline unsigned int count_digits(number_unsigned_t x) noexcept
17066 {
17067 unsigned int n_digits = 1;
17068 for (;;)
17069 {
17070 if (x < 10)
17071 {
17072 return n_digits;
17073 }
17074 if (x < 100)
17075 {
17076 return n_digits + 1;
17077 }
17078 if (x < 1000)
17079 {
17080 return n_digits + 2;
17081 }
17082 if (x < 10000)
17083 {
17084 return n_digits + 3;
17085 }
17086 x = x / 10000u;
17087 n_digits += 4;
17088 }
17089 }
17090
17100 template < typename NumberType, detail::enable_if_t <
17101 std::is_integral<NumberType>::value ||
17102 std::is_same<NumberType, number_unsigned_t>::value ||
17103 std::is_same<NumberType, number_integer_t>::value ||
17104 std::is_same<NumberType, binary_char_t>::value,
17105 int > = 0 >
17106 void dump_integer(NumberType x)
17107 {
17108 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
17109 {
17110 {
17111 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
17112 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
17113 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
17114 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
17115 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
17116 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
17117 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
17118 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
17119 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
17120 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
17121 }
17122 };
17123
17124 // special case for "0"
17125 if (x == 0)
17126 {
17127 o->write_character('0');
17128 return;
17129 }
17130
17131 // use a pointer to fill the buffer
17132 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17133
17134 const bool is_negative = std::is_signed<NumberType>::value && !(x >= 0); // see issue #755
17135 number_unsigned_t abs_value;
17136
17137 unsigned int n_chars{};
17138
17139 if (is_negative)
17140 {
17141 *buffer_ptr = '-';
17142 abs_value = remove_sign(static_cast<number_integer_t>(x));
17143
17144 // account one more byte for the minus sign
17145 n_chars = 1 + count_digits(abs_value);
17146 }
17147 else
17148 {
17149 abs_value = static_cast<number_unsigned_t>(x);
17150 n_chars = count_digits(abs_value);
17151 }
17152
17153 // spare 1 byte for '\0'
17154 JSON_ASSERT(n_chars < number_buffer.size() - 1);
17155
17156 // jump to the end to generate the string from backward
17157 // so we later avoid reversing the result
17158 buffer_ptr += n_chars;
17159
17160 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
17161 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
17162 while (abs_value >= 100)
17163 {
17164 const auto digits_index = static_cast<unsigned>((abs_value % 100));
17165 abs_value /= 100;
17166 *(--buffer_ptr) = digits_to_99[digits_index][1];
17167 *(--buffer_ptr) = digits_to_99[digits_index][0];
17168 }
17169
17170 if (abs_value >= 10)
17171 {
17172 const auto digits_index = static_cast<unsigned>(abs_value);
17173 *(--buffer_ptr) = digits_to_99[digits_index][1];
17174 *(--buffer_ptr) = digits_to_99[digits_index][0];
17175 }
17176 else
17177 {
17178 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
17179 }
17180
17181 o->write_characters(number_buffer.data(), n_chars);
17182 }
17183
17192 void dump_float(number_float_t x)
17193 {
17194 // NaN / inf
17195 if (!std::isfinite(x))
17196 {
17197 o->write_characters("null", 4);
17198 return;
17199 }
17200
17201 // If number_float_t is an IEEE-754 single or double precision number,
17202 // use the Grisu2 algorithm to produce short numbers which are
17203 // guaranteed to round-trip, using strtof and strtod, resp.
17204 //
17205 // NB: The test below works if <long double> == <double>.
17206 static constexpr bool is_ieee_single_or_double
17207 = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
17208 (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
17209
17210 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
17211 }
17212
17213 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
17214 {
17215 auto* begin = number_buffer.data();
17216 auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
17217
17218 o->write_characters(begin, static_cast<size_t>(end - begin));
17219 }
17220
17221 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
17222 {
17223 // get number of digits for a float -> text -> float round-trip
17224 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
17225
17226 // the actual conversion
17227 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17228 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
17229
17230 // negative value indicates an error
17231 JSON_ASSERT(len > 0);
17232 // check if buffer was large enough
17233 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
17234
17235 // erase thousands separator
17236 if (thousands_sep != '\0')
17237 {
17238 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
17239 const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
17240 std::fill(end, number_buffer.end(), '\0');
17241 JSON_ASSERT((end - number_buffer.begin()) <= len);
17242 len = (end - number_buffer.begin());
17243 }
17244
17245 // convert decimal point to '.'
17246 if (decimal_point != '\0' && decimal_point != '.')
17247 {
17248 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
17249 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
17250 if (dec_pos != number_buffer.end())
17251 {
17252 *dec_pos = '.';
17253 }
17254 }
17255
17256 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
17257
17258 // determine if need to append ".0"
17259 const bool value_is_int_like =
17260 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
17261 [](char c)
17262 {
17263 return c == '.' || c == 'e';
17264 });
17265
17266 if (value_is_int_like)
17267 {
17268 o->write_characters(".0", 2);
17269 }
17270 }
17271
17293 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
17294 {
17295 static const std::array<std::uint8_t, 400> utf8d =
17296 {
17297 {
17298 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
17299 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
17300 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
17301 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
17302 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
17303 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
17304 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
17305 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
17306 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
17307 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
17308 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
17309 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
17310 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
17311 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
17312 }
17313 };
17314
17315 JSON_ASSERT(byte < utf8d.size());
17316 const std::uint8_t type = utf8d[byte];
17317
17318 codep = (state != UTF8_ACCEPT)
17319 ? (byte & 0x3fu) | (codep << 6u)
17320 : (0xFFu >> type) & (byte);
17321
17322 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
17323 JSON_ASSERT(index < 400);
17324 state = utf8d[index];
17325 return state;
17326 }
17327
17328 /*
17329 * Overload to make the compiler happy while it is instantiating
17330 * dump_integer for number_unsigned_t.
17331 * Must never be called.
17332 */
17334 {
17335 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17336 return x; // LCOV_EXCL_LINE
17337 }
17338
17339 /*
17340 * Helper function for dump_integer
17341 *
17342 * This function takes a negative signed integer and returns its absolute
17343 * value as unsigned integer. The plus/minus shuffling is necessary as we can
17344 * not directly remove the sign of an arbitrary signed integer as the
17345 * absolute values of INT_MIN and INT_MAX are usually not the same. See
17346 * #1708 for details.
17347 */
17348 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
17349 {
17350 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
17351 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
17352 }
17353
17354 private:
17356 output_adapter_t<char> o = nullptr;
17357
17359 std::array<char, 64> number_buffer{{}};
17360
17362 const std::lconv* loc = nullptr;
17364 const char thousands_sep = '\0';
17366 const char decimal_point = '\0';
17367
17369 std::array<char, 512> string_buffer{{}};
17370
17372 const char indent_char;
17375
17378};
17379} // namespace detail
17380} // namespace nlohmann
17381
17382// #include <nlohmann/detail/value_t.hpp>
17383
17384// #include <nlohmann/json_fwd.hpp>
17385
17386// #include <nlohmann/ordered_map.hpp>
17387
17388
17389#include <functional> // less
17390#include <initializer_list> // initializer_list
17391#include <iterator> // input_iterator_tag, iterator_traits
17392#include <memory> // allocator
17393#include <stdexcept> // for out_of_range
17394#include <type_traits> // enable_if, is_convertible
17395#include <utility> // pair
17396#include <vector> // vector
17397
17398// #include <nlohmann/detail/macro_scope.hpp>
17399
17400
17401namespace nlohmann
17402{
17403
17406template <class Key, class T, class IgnoredLess = std::less<Key>,
17407 class Allocator = std::allocator<std::pair<const Key, T>>>
17408 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
17409{
17410 using key_type = Key;
17411 using mapped_type = T;
17412 using Container = std::vector<std::pair<const Key, T>, Allocator>;
17413 using typename Container::iterator;
17414 using typename Container::const_iterator;
17415 using typename Container::size_type;
17416 using typename Container::value_type;
17417
17418 // Explicit constructors instead of `using Container::Container`
17419 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
17420 ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
17421 template <class It>
17422 ordered_map(It first, It last, const Allocator& alloc = Allocator())
17423 : Container{first, last, alloc} {}
17424 ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
17425 : Container{init, alloc} {}
17426
17427 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
17428 {
17429 for (auto it = this->begin(); it != this->end(); ++it)
17430 {
17431 if (it->first == key)
17432 {
17433 return {it, false};
17434 }
17435 }
17436 Container::emplace_back(key, t);
17437 return {--this->end(), true};
17438 }
17439
17440 T& operator[](const Key& key)
17441 {
17442 return emplace(key, T{}).first->second;
17443 }
17444
17445 const T& operator[](const Key& key) const
17446 {
17447 return at(key);
17448 }
17449
17450 T& at(const Key& key)
17451 {
17452 for (auto it = this->begin(); it != this->end(); ++it)
17453 {
17454 if (it->first == key)
17455 {
17456 return it->second;
17457 }
17458 }
17459
17460 JSON_THROW(std::out_of_range("key not found"));
17461 }
17462
17463 const T& at(const Key& key) const
17464 {
17465 for (auto it = this->begin(); it != this->end(); ++it)
17466 {
17467 if (it->first == key)
17468 {
17469 return it->second;
17470 }
17471 }
17472
17473 JSON_THROW(std::out_of_range("key not found"));
17474 }
17475
17476 size_type erase(const Key& key)
17477 {
17478 for (auto it = this->begin(); it != this->end(); ++it)
17479 {
17480 if (it->first == key)
17481 {
17482 // Since we cannot move const Keys, re-construct them in place
17483 for (auto next = it; ++next != this->end(); ++it)
17484 {
17485 it->~value_type(); // Destroy but keep allocation
17486 new (&*it) value_type{std::move(*next)};
17487 }
17488 Container::pop_back();
17489 return 1;
17490 }
17491 }
17492 return 0;
17493 }
17494
17495 iterator erase(iterator pos)
17496 {
17497 return erase(pos, std::next(pos));
17498 }
17499
17500 iterator erase(iterator first, iterator last)
17501 {
17502 const auto elements_affected = std::distance(first, last);
17503 const auto offset = std::distance(Container::begin(), first);
17504
17505 // This is the start situation. We need to delete elements_affected
17506 // elements (3 in this example: e, f, g), and need to return an
17507 // iterator past the last deleted element (h in this example).
17508 // Note that offset is the distance from the start of the vector
17509 // to first. We will need this later.
17510
17511 // [ a, b, c, d, e, f, g, h, i, j ]
17512 // ^ ^
17513 // first last
17514
17515 // Since we cannot move const Keys, we re-construct them in place.
17516 // We start at first and re-construct (viz. copy) the elements from
17517 // the back of the vector. Example for first iteration:
17518
17519 // ,--------.
17520 // v | destroy e and re-construct with h
17521 // [ a, b, c, d, e, f, g, h, i, j ]
17522 // ^ ^
17523 // it it + elements_affected
17524
17525 for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
17526 {
17527 it->~value_type(); // destroy but keep allocation
17528 new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
17529 }
17530
17531 // [ a, b, c, d, h, i, j, h, i, j ]
17532 // ^ ^
17533 // first last
17534
17535 // remove the unneeded elements at the end of the vector
17536 Container::resize(this->size() - static_cast<size_type>(elements_affected));
17537
17538 // [ a, b, c, d, h, i, j ]
17539 // ^ ^
17540 // first last
17541
17542 // first is now pointing past the last deleted element, but we cannot
17543 // use this iterator, because it may have been invalidated by the
17544 // resize call. Instead, we can return begin() + offset.
17545 return Container::begin() + offset;
17546 }
17547
17548 size_type count(const Key& key) const
17549 {
17550 for (auto it = this->begin(); it != this->end(); ++it)
17551 {
17552 if (it->first == key)
17553 {
17554 return 1;
17555 }
17556 }
17557 return 0;
17558 }
17559
17560 iterator find(const Key& key)
17561 {
17562 for (auto it = this->begin(); it != this->end(); ++it)
17563 {
17564 if (it->first == key)
17565 {
17566 return it;
17567 }
17568 }
17569 return Container::end();
17570 }
17571
17572 const_iterator find(const Key& key) const
17573 {
17574 for (auto it = this->begin(); it != this->end(); ++it)
17575 {
17576 if (it->first == key)
17577 {
17578 return it;
17579 }
17580 }
17581 return Container::end();
17582 }
17583
17584 std::pair<iterator, bool> insert( value_type&& value )
17585 {
17586 return emplace(value.first, std::move(value.second));
17587 }
17588
17589 std::pair<iterator, bool> insert( const value_type& value )
17590 {
17591 for (auto it = this->begin(); it != this->end(); ++it)
17592 {
17593 if (it->first == value.first)
17594 {
17595 return {it, false};
17596 }
17597 }
17598 Container::push_back(value);
17599 return {--this->end(), true};
17600 }
17601
17602 template<typename InputIt>
17603 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
17604 std::input_iterator_tag>::value>::type;
17605
17606 template<typename InputIt, typename = require_input_iter<InputIt>>
17607 void insert(InputIt first, InputIt last)
17608 {
17609 for (auto it = first; it != last; ++it)
17610 {
17611 insert(*it);
17612 }
17613 }
17614};
17615
17616} // namespace nlohmann
17617
17618
17619#if defined(JSON_HAS_CPP_17)
17620 #include <string_view>
17621#endif
17622
17628namespace nlohmann
17629{
17630
17716class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
17717{
17718 private:
17719 template<detail::value_t> friend struct detail::external_constructor;
17720 friend ::nlohmann::json_pointer<basic_json>;
17721
17722 template<typename BasicJsonType, typename InputType>
17723 friend class ::nlohmann::detail::parser;
17724 friend ::nlohmann::detail::serializer<basic_json>;
17725 template<typename BasicJsonType>
17726 friend class ::nlohmann::detail::iter_impl;
17727 template<typename BasicJsonType, typename CharType>
17728 friend class ::nlohmann::detail::binary_writer;
17729 template<typename BasicJsonType, typename InputType, typename SAX>
17730 friend class ::nlohmann::detail::binary_reader;
17731 template<typename BasicJsonType>
17732 friend class ::nlohmann::detail::json_sax_dom_parser;
17733 template<typename BasicJsonType>
17734 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
17735 friend class ::nlohmann::detail::exception;
17736
17739
17741 // convenience aliases for types residing in namespace detail;
17743
17744 template<typename InputAdapterType>
17745 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
17746 InputAdapterType adapter,
17748 const bool allow_exceptions = true,
17749 const bool ignore_comments = false
17750 )
17751 {
17752 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
17753 std::move(cb), allow_exceptions, ignore_comments);
17754 }
17755
17756 private:
17758 template<typename BasicJsonType>
17760 template<typename BasicJsonType>
17762 template<typename Iterator>
17765
17766 template<typename CharType>
17768
17769 template<typename InputType>
17772
17775
17776 public:
17780 template<typename T, typename SFINAE>
17781 using json_serializer = JSONSerializer<T, SFINAE>;
17787 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
17788
17792
17794 // exceptions //
17796
17800
17813
17815
17816
17818 // container types //
17820
17825
17828
17833
17835 using difference_type = std::ptrdiff_t;
17837 using size_type = std::size_t;
17838
17840 using allocator_type = AllocatorType<basic_json>;
17841
17843 using pointer = typename std::allocator_traits<allocator_type>::pointer;
17845 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
17846
17855
17857
17858
17863 {
17864 return allocator_type();
17865 }
17866
17895 {
17896 basic_json result;
17897
17898 result["copyright"] = "(C) 2013-2021 Niels Lohmann";
17899 result["name"] = "JSON for Modern C++";
17900 result["url"] = "https://github.com/nlohmann/json";
17901 result["version"]["string"] =
17902 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
17903 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
17904 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
17905 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
17906 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
17907 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
17908
17909#ifdef _WIN32
17910 result["platform"] = "win32";
17911#elif defined __linux__
17912 result["platform"] = "linux";
17913#elif defined __APPLE__
17914 result["platform"] = "apple";
17915#elif defined __unix__
17916 result["platform"] = "unix";
17917#else
17918 result["platform"] = "unknown";
17919#endif
17920
17921#if defined(__ICC) || defined(__INTEL_COMPILER)
17922 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
17923#elif defined(__clang__)
17924 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
17925#elif defined(__GNUC__) || defined(__GNUG__)
17926 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
17927#elif defined(__HP_cc) || defined(__HP_aCC)
17928 result["compiler"] = "hp"
17929#elif defined(__IBMCPP__)
17930 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
17931#elif defined(_MSC_VER)
17932 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
17933#elif defined(__PGI)
17934 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
17935#elif defined(__SUNPRO_CC)
17936 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
17937#else
17938 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
17939#endif
17940
17941#ifdef __cplusplus
17942 result["compiler"]["c++"] = std::to_string(__cplusplus);
17943#else
17944 result["compiler"]["c++"] = "unknown";
17945#endif
17946 return result;
17947 }
17948
17949
17951 // JSON value data types //
17953
17958
17959#if defined(JSON_HAS_CPP_14)
17960 // Use transparent comparator if possible, combined with perfect forwarding
17961 // on find() and count() calls prevents unnecessary string construction.
17962 using object_comparator_t = std::less<>;
17963#else
17964 using object_comparator_t = std::less<StringType>;
17965#endif
17966
18050 using object_t = ObjectType<StringType,
18051 basic_json,
18053 AllocatorType<std::pair<const StringType,
18054 basic_json>>>;
18055
18100 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
18101
18153 using string_t = StringType;
18154
18179 using boolean_t = BooleanType;
18180
18251 using number_integer_t = NumberIntegerType;
18252
18322 using number_unsigned_t = NumberUnsignedType;
18323
18390 using number_float_t = NumberFloatType;
18391
18463
18464 private:
18465
18467 template<typename T, typename... Args>
18469 static T* create(Args&& ... args)
18470 {
18471 AllocatorType<T> alloc;
18472 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18473
18474 auto deleter = [&](T * obj)
18475 {
18476 AllocatorTraits::deallocate(alloc, obj, 1);
18477 };
18478 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18479 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18480 JSON_ASSERT(obj != nullptr);
18481 return obj.release();
18482 }
18483
18485 // JSON value storage //
18487
18514 union json_value
18515 {
18532
18534 json_value() = default;
18536 json_value(boolean_t v) noexcept : boolean(v) {}
18545 {
18546 switch (t)
18547 {
18548 case value_t::object:
18549 {
18550 object = create<object_t>();
18551 break;
18552 }
18553
18554 case value_t::array:
18555 {
18556 array = create<array_t>();
18557 break;
18558 }
18559
18560 case value_t::string:
18561 {
18562 string = create<string_t>("");
18563 break;
18564 }
18565
18566 case value_t::binary:
18567 {
18568 binary = create<binary_t>();
18569 break;
18570 }
18571
18572 case value_t::boolean:
18573 {
18574 boolean = boolean_t(false);
18575 break;
18576 }
18577
18578 case value_t::number_integer:
18579 {
18581 break;
18582 }
18583
18584 case value_t::number_unsigned:
18585 {
18587 break;
18588 }
18589
18590 case value_t::number_float:
18591 {
18593 break;
18594 }
18595
18596 case value_t::null:
18597 {
18598 object = nullptr; // silence warning, see #821
18599 break;
18600 }
18601
18602 case value_t::discarded:
18603 default:
18604 {
18605 object = nullptr; // silence warning, see #821
18606 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
18607 {
18608 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.4", basic_json())); // LCOV_EXCL_LINE
18609 }
18610 break;
18611 }
18612 }
18613 }
18614
18617
18620
18623
18626
18629
18632
18635
18638
18641
18644
18646 {
18647 if (t == value_t::array || t == value_t::object)
18648 {
18649 // flatten the current json_value to a heap-allocated stack
18650 std::vector<basic_json> stack;
18651
18652 // move the top-level items to stack
18653 if (t == value_t::array)
18654 {
18655 stack.reserve(array->size());
18656 std::move(array->begin(), array->end(), std::back_inserter(stack));
18657 }
18658 else
18659 {
18660 stack.reserve(object->size());
18661 for (auto&& it : *object)
18662 {
18663 stack.push_back(std::move(it.second));
18664 }
18665 }
18666
18667 while (!stack.empty())
18668 {
18669 // move the last item to local variable to be processed
18670 basic_json current_item(std::move(stack.back()));
18671 stack.pop_back();
18672
18673 // if current_item is array/object, move
18674 // its children to the stack to be processed later
18675 if (current_item.is_array())
18676 {
18677 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
18678
18679 current_item.m_value.array->clear();
18680 }
18681 else if (current_item.is_object())
18682 {
18683 for (auto&& it : *current_item.m_value.object)
18684 {
18685 stack.push_back(std::move(it.second));
18686 }
18687
18688 current_item.m_value.object->clear();
18689 }
18690
18691 // it's now safe that current_item get destructed
18692 // since it doesn't have any children
18693 }
18694 }
18695
18696 switch (t)
18697 {
18698 case value_t::object:
18699 {
18700 AllocatorType<object_t> alloc;
18701 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18702 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18703 break;
18704 }
18705
18706 case value_t::array:
18707 {
18708 AllocatorType<array_t> alloc;
18709 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18710 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18711 break;
18712 }
18713
18714 case value_t::string:
18715 {
18716 AllocatorType<string_t> alloc;
18717 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18718 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18719 break;
18720 }
18721
18722 case value_t::binary:
18723 {
18724 AllocatorType<binary_t> alloc;
18725 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18726 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18727 break;
18728 }
18729
18730 case value_t::null:
18731 case value_t::boolean:
18732 case value_t::number_integer:
18733 case value_t::number_unsigned:
18734 case value_t::number_float:
18735 case value_t::discarded:
18736 default:
18737 {
18738 break;
18739 }
18740 }
18741 }
18742 };
18743
18744 private:
18763 void assert_invariant(bool check_parents = true) const noexcept
18764 {
18765 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18766 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18767 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18768 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18769
18770#if JSON_DIAGNOSTICS
18771 JSON_TRY
18772 {
18773 // cppcheck-suppress assertWithSideEffect
18774 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
18775 {
18776 return j.m_parent == this;
18777 }));
18778 }
18779 JSON_CATCH(...) {} // LCOV_EXCL_LINE
18780#endif
18781 static_cast<void>(check_parents);
18782 }
18783
18785 {
18786#if JSON_DIAGNOSTICS
18787 switch (m_type)
18788 {
18789 case value_t::array:
18790 {
18791 for (auto& element : *m_value.array)
18792 {
18793 element.m_parent = this;
18794 }
18795 break;
18796 }
18797
18798 case value_t::object:
18799 {
18800 for (auto& element : *m_value.object)
18801 {
18802 element.second.m_parent = this;
18803 }
18804 break;
18805 }
18806
18807 case value_t::null:
18808 case value_t::string:
18809 case value_t::boolean:
18810 case value_t::number_integer:
18811 case value_t::number_unsigned:
18812 case value_t::number_float:
18813 case value_t::binary:
18814 case value_t::discarded:
18815 default:
18816 break;
18817 }
18818#endif
18819 }
18820
18822 {
18823#if JSON_DIAGNOSTICS
18824 for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
18825 {
18826 (it + i)->m_parent = this;
18827 }
18828#else
18829 static_cast<void>(count_set_parents);
18830#endif
18831 return it;
18832 }
18833
18834 reference set_parent(reference j, std::size_t old_capacity = std::size_t(-1))
18835 {
18836#if JSON_DIAGNOSTICS
18837 if (old_capacity != std::size_t(-1))
18838 {
18839 // see https://github.com/nlohmann/json/issues/2838
18840 JSON_ASSERT(type() == value_t::array);
18841 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
18842 {
18843 // capacity has changed: update all parents
18844 set_parents();
18845 return j;
18846 }
18847 }
18848
18849 // ordered_json uses a vector internally, so pointers could have
18850 // been invalidated; see https://github.com/nlohmann/json/issues/2962
18851#ifdef JSON_HEDLEY_MSVC_VERSION
18852#pragma warning(push )
18853#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
18854#endif
18856 {
18857 set_parents();
18858 return j;
18859 }
18860#ifdef JSON_HEDLEY_MSVC_VERSION
18861#pragma warning( pop )
18862#endif
18863
18864 j.m_parent = this;
18865#else
18866 static_cast<void>(j);
18867 static_cast<void>(old_capacity);
18868#endif
18869 return j;
18870 }
18871
18872 public:
18874 // JSON parser callback //
18876
18893
18944
18946 // constructors //
18948
18953
18985 : m_type(v), m_value(v)
18986 {
18988 }
18989
19008 basic_json(std::nullptr_t = nullptr) noexcept
19009 : basic_json(value_t::null)
19010 {
19012 }
19013
19076 template < typename CompatibleType,
19080 basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
19081 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
19082 std::forward<CompatibleType>(val))))
19083 {
19084 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
19085 set_parents();
19087 }
19088
19115 template < typename BasicJsonType,
19117 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
19118 basic_json(const BasicJsonType& val)
19119 {
19120 using other_boolean_t = typename BasicJsonType::boolean_t;
19121 using other_number_float_t = typename BasicJsonType::number_float_t;
19122 using other_number_integer_t = typename BasicJsonType::number_integer_t;
19123 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
19124 using other_string_t = typename BasicJsonType::string_t;
19125 using other_object_t = typename BasicJsonType::object_t;
19126 using other_array_t = typename BasicJsonType::array_t;
19127 using other_binary_t = typename BasicJsonType::binary_t;
19128
19129 switch (val.type())
19130 {
19131 case value_t::boolean:
19132 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
19133 break;
19134 case value_t::number_float:
19135 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
19136 break;
19137 case value_t::number_integer:
19138 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
19139 break;
19140 case value_t::number_unsigned:
19141 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
19142 break;
19143 case value_t::string:
19144 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
19145 break;
19146 case value_t::object:
19147 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
19148 break;
19149 case value_t::array:
19150 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
19151 break;
19152 case value_t::binary:
19153 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
19154 break;
19155 case value_t::null:
19156 *this = nullptr;
19157 break;
19158 case value_t::discarded:
19159 m_type = value_t::discarded;
19160 break;
19161 default: // LCOV_EXCL_LINE
19162 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19163 }
19164 set_parents();
19166 }
19167
19243 bool type_deduction = true,
19244 value_t manual_type = value_t::array)
19245 {
19246 // check if each element is an array with two elements whose first
19247 // element is a string
19248 bool is_an_object = std::all_of(init.begin(), init.end(),
19249 [](const detail::json_ref<basic_json>& element_ref)
19250 {
19251 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19252 });
19253
19254 // adjust type if type deduction is not wanted
19255 if (!type_deduction)
19256 {
19257 // if array is wanted, do not create an object though possible
19258 if (manual_type == value_t::array)
19259 {
19260 is_an_object = false;
19261 }
19262
19263 // if object is wanted but impossible, throw an exception
19264 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
19265 {
19266 JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
19267 }
19268 }
19269
19270 if (is_an_object)
19271 {
19272 // the initializer list is a list of pairs -> create object
19273 m_type = value_t::object;
19274 m_value = value_t::object;
19275
19276 for (auto& element_ref : init)
19277 {
19278 auto element = element_ref.moved_or_copied();
19279 m_value.object->emplace(
19280 std::move(*((*element.m_value.array)[0].m_value.string)),
19281 std::move((*element.m_value.array)[1]));
19282 }
19283 }
19284 else
19285 {
19286 // the initializer list describes an array -> create array
19287 m_type = value_t::array;
19288 m_value.array = create<array_t>(init.begin(), init.end());
19289 }
19290
19291 set_parents();
19293 }
19294
19323 static basic_json binary(const typename binary_t::container_type& init)
19324 {
19325 auto res = basic_json();
19326 res.m_type = value_t::binary;
19327 res.m_value = init;
19328 return res;
19329 }
19330
19360 static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
19361 {
19362 auto res = basic_json();
19363 res.m_type = value_t::binary;
19364 res.m_value = binary_t(init, subtype);
19365 return res;
19366 }
19367
19371 {
19372 auto res = basic_json();
19373 res.m_type = value_t::binary;
19374 res.m_value = std::move(init);
19375 return res;
19376 }
19377
19380 static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
19381 {
19382 auto res = basic_json();
19383 res.m_type = value_t::binary;
19384 res.m_value = binary_t(std::move(init), subtype);
19385 return res;
19386 }
19387
19427 {
19428 return basic_json(init, false, value_t::array);
19429 }
19430
19471 {
19472 return basic_json(init, false, value_t::object);
19473 }
19474
19498 : m_type(value_t::array)
19499 {
19500 m_value.array = create<array_t>(cnt, val);
19501 set_parents();
19503 }
19504
19560 template < class InputIT, typename std::enable_if <
19561 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19562 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19563 basic_json(InputIT first, InputIT last)
19564 {
19565 JSON_ASSERT(first.m_object != nullptr);
19566 JSON_ASSERT(last.m_object != nullptr);
19567
19568 // make sure iterator fits the current value
19569 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19570 {
19571 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
19572 }
19573
19574 // copy type from first iterator
19575 m_type = first.m_object->m_type;
19576
19577 // check if iterator range is complete for primitive values
19578 switch (m_type)
19579 {
19580 case value_t::boolean:
19581 case value_t::number_float:
19582 case value_t::number_integer:
19583 case value_t::number_unsigned:
19584 case value_t::string:
19585 {
19586 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19587 || !last.m_it.primitive_iterator.is_end()))
19588 {
19589 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
19590 }
19591 break;
19592 }
19593
19594 case value_t::null:
19595 case value_t::object:
19596 case value_t::array:
19597 case value_t::binary:
19598 case value_t::discarded:
19599 default:
19600 break;
19601 }
19602
19603 switch (m_type)
19604 {
19605 case value_t::number_integer:
19606 {
19607 m_value.number_integer = first.m_object->m_value.number_integer;
19608 break;
19609 }
19610
19611 case value_t::number_unsigned:
19612 {
19613 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19614 break;
19615 }
19616
19617 case value_t::number_float:
19618 {
19619 m_value.number_float = first.m_object->m_value.number_float;
19620 break;
19621 }
19622
19623 case value_t::boolean:
19624 {
19625 m_value.boolean = first.m_object->m_value.boolean;
19626 break;
19627 }
19628
19629 case value_t::string:
19630 {
19631 m_value = *first.m_object->m_value.string;
19632 break;
19633 }
19634
19635 case value_t::object:
19636 {
19637 m_value.object = create<object_t>(first.m_it.object_iterator,
19638 last.m_it.object_iterator);
19639 break;
19640 }
19641
19642 case value_t::array:
19643 {
19644 m_value.array = create<array_t>(first.m_it.array_iterator,
19645 last.m_it.array_iterator);
19646 break;
19647 }
19648
19649 case value_t::binary:
19650 {
19651 m_value = *first.m_object->m_value.binary;
19652 break;
19653 }
19654
19655 case value_t::null:
19656 case value_t::discarded:
19657 default:
19658 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
19659 }
19660
19661 set_parents();
19663 }
19664
19665
19667 // other constructors and destructor //
19669
19670 template<typename JsonRef,
19672 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
19673 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19674
19701 : m_type(other.m_type)
19702 {
19703 // check of passed value is valid
19704 other.assert_invariant();
19705
19706 switch (m_type)
19707 {
19708 case value_t::object:
19709 {
19710 m_value = *other.m_value.object;
19711 break;
19712 }
19713
19714 case value_t::array:
19715 {
19716 m_value = *other.m_value.array;
19717 break;
19718 }
19719
19720 case value_t::string:
19721 {
19722 m_value = *other.m_value.string;
19723 break;
19724 }
19725
19726 case value_t::boolean:
19727 {
19728 m_value = other.m_value.boolean;
19729 break;
19730 }
19731
19732 case value_t::number_integer:
19733 {
19734 m_value = other.m_value.number_integer;
19735 break;
19736 }
19737
19738 case value_t::number_unsigned:
19739 {
19740 m_value = other.m_value.number_unsigned;
19741 break;
19742 }
19743
19744 case value_t::number_float:
19745 {
19746 m_value = other.m_value.number_float;
19747 break;
19748 }
19749
19750 case value_t::binary:
19751 {
19752 m_value = *other.m_value.binary;
19753 break;
19754 }
19755
19756 case value_t::null:
19757 case value_t::discarded:
19758 default:
19759 break;
19760 }
19761
19762 set_parents();
19764 }
19765
19792 basic_json(basic_json&& other) noexcept
19793 : m_type(std::move(other.m_type)),
19794 m_value(std::move(other.m_value))
19795 {
19796 // check that passed value is valid
19797 other.assert_invariant(false);
19798
19799 // invalidate payload
19800 other.m_type = value_t::null;
19801 other.m_value = {};
19802
19803 set_parents();
19805 }
19806
19831 std::is_nothrow_move_constructible<value_t>::value&&
19832 std::is_nothrow_move_assignable<value_t>::value&&
19833 std::is_nothrow_move_constructible<json_value>::value&&
19834 std::is_nothrow_move_assignable<json_value>::value
19835 )
19836 {
19837 // check that passed value is valid
19838 other.assert_invariant();
19839
19840 using std::swap;
19841 swap(m_type, other.m_type);
19842 swap(m_value, other.m_value);
19843
19844 set_parents();
19846 return *this;
19847 }
19848
19864 ~basic_json() noexcept
19865 {
19866 assert_invariant(false);
19867 m_value.destroy(m_type);
19868 }
19869
19871
19872 public:
19874 // object inspection //
19876
19880
19928 string_t dump(const int indent = -1,
19929 const char indent_char = ' ',
19930 const bool ensure_ascii = false,
19931 const error_handler_t error_handler = error_handler_t::strict) const
19932 {
19933 string_t result;
19934 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
19935
19936 if (indent >= 0)
19937 {
19938 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19939 }
19940 else
19941 {
19942 s.dump(*this, false, ensure_ascii, 0);
19943 }
19944
19945 return result;
19946 }
19947
19981 constexpr value_t type() const noexcept
19982 {
19983 return m_type;
19984 }
19985
20012 constexpr bool is_primitive() const noexcept
20013 {
20014 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
20015 }
20016
20039 constexpr bool is_structured() const noexcept
20040 {
20041 return is_array() || is_object();
20042 }
20043
20061 constexpr bool is_null() const noexcept
20062 {
20063 return m_type == value_t::null;
20064 }
20065
20083 constexpr bool is_boolean() const noexcept
20084 {
20085 return m_type == value_t::boolean;
20086 }
20087
20113 constexpr bool is_number() const noexcept
20114 {
20115 return is_number_integer() || is_number_float();
20116 }
20117
20142 constexpr bool is_number_integer() const noexcept
20143 {
20144 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
20145 }
20146
20170 constexpr bool is_number_unsigned() const noexcept
20171 {
20172 return m_type == value_t::number_unsigned;
20173 }
20174
20198 constexpr bool is_number_float() const noexcept
20199 {
20200 return m_type == value_t::number_float;
20201 }
20202
20220 constexpr bool is_object() const noexcept
20221 {
20222 return m_type == value_t::object;
20223 }
20224
20242 constexpr bool is_array() const noexcept
20243 {
20244 return m_type == value_t::array;
20245 }
20246
20264 constexpr bool is_string() const noexcept
20265 {
20266 return m_type == value_t::string;
20267 }
20268
20286 constexpr bool is_binary() const noexcept
20287 {
20288 return m_type == value_t::binary;
20289 }
20290
20313 constexpr bool is_discarded() const noexcept
20314 {
20315 return m_type == value_t::discarded;
20316 }
20317
20339 constexpr operator value_t() const noexcept
20340 {
20341 return m_type;
20342 }
20343
20345
20346 private:
20348 // value access //
20350
20352 boolean_t get_impl(boolean_t* /*unused*/) const
20353 {
20355 {
20356 return m_value.boolean;
20357 }
20358
20359 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
20360 }
20361
20363 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20364 {
20365 return is_object() ? m_value.object : nullptr;
20366 }
20367
20369 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20370 {
20371 return is_object() ? m_value.object : nullptr;
20372 }
20373
20375 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20376 {
20377 return is_array() ? m_value.array : nullptr;
20378 }
20379
20381 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20382 {
20383 return is_array() ? m_value.array : nullptr;
20384 }
20385
20387 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20388 {
20389 return is_string() ? m_value.string : nullptr;
20390 }
20391
20393 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20394 {
20395 return is_string() ? m_value.string : nullptr;
20396 }
20397
20399 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20400 {
20401 return is_boolean() ? &m_value.boolean : nullptr;
20402 }
20403
20405 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20406 {
20407 return is_boolean() ? &m_value.boolean : nullptr;
20408 }
20409
20412 {
20413 return is_number_integer() ? &m_value.number_integer : nullptr;
20414 }
20415
20417 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20418 {
20419 return is_number_integer() ? &m_value.number_integer : nullptr;
20420 }
20421
20424 {
20425 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20426 }
20427
20429 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20430 {
20431 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20432 }
20433
20436 {
20437 return is_number_float() ? &m_value.number_float : nullptr;
20438 }
20439
20441 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20442 {
20443 return is_number_float() ? &m_value.number_float : nullptr;
20444 }
20445
20447 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20448 {
20449 return is_binary() ? m_value.binary : nullptr;
20450 }
20451
20453 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20454 {
20455 return is_binary() ? m_value.binary : nullptr;
20456 }
20457
20469 template<typename ReferenceType, typename ThisType>
20470 static ReferenceType get_ref_impl(ThisType& obj)
20471 {
20472 // delegate the call to get_ptr<>()
20473 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20474
20475 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20476 {
20477 return *ptr;
20478 }
20479
20480 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
20481 }
20482
20483 public:
20487
20514 template<typename PointerType, typename std::enable_if<
20515 std::is_pointer<PointerType>::value, int>::type = 0>
20516 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20517 {
20518 // delegate the call to get_impl_ptr<>()
20519 return get_impl_ptr(static_cast<PointerType>(nullptr));
20520 }
20521
20526 template < typename PointerType, typename std::enable_if <
20527 std::is_pointer<PointerType>::value&&
20528 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
20529 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20530 {
20531 // delegate the call to get_impl_ptr<>() const
20532 return get_impl_ptr(static_cast<PointerType>(nullptr));
20533 }
20534
20535 private:
20574 template < typename ValueType,
20578 int > = 0 >
20579 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20580 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20581 {
20582 auto ret = ValueType();
20583 JSONSerializer<ValueType>::from_json(*this, ret);
20584 return ret;
20585 }
20586
20617 template < typename ValueType,
20620 int > = 0 >
20621 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20622 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20623 {
20624 return JSONSerializer<ValueType>::from_json(*this);
20625 }
20626
20642 template < typename BasicJsonType,
20645 int > = 0 >
20646 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20647 {
20648 return *this;
20649 }
20650
20665 template<typename BasicJsonType,
20667 std::is_same<BasicJsonType, basic_json_t>::value,
20668 int> = 0>
20670 {
20671 return *this;
20672 }
20673
20678 template<typename PointerType,
20680 std::is_pointer<PointerType>::value,
20681 int> = 0>
20682 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20683 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20684 {
20685 // delegate the call to get_ptr
20686 return get_ptr<PointerType>();
20687 }
20688
20689 public:
20713 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20714#if defined(JSON_HAS_CPP_14)
20715 constexpr
20716#endif
20717 auto get() const noexcept(
20718 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20719 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20720 {
20721 // we cannot static_assert on ValueTypeCV being non-const, because
20722 // there is support for get<const basic_json_t>(), which is why we
20723 // still need the uncvref
20724 static_assert(!std::is_reference<ValueTypeCV>::value,
20725 "get() cannot be used with reference types, you might want to use get_ref()");
20726 return get_impl<ValueType>(detail::priority_tag<4> {});
20727 }
20728
20756 template<typename PointerType, typename std::enable_if<
20757 std::is_pointer<PointerType>::value, int>::type = 0>
20758 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20759 {
20760 // delegate the call to get_ptr
20761 return get_ptr<PointerType>();
20762 }
20763
20797 template < typename ValueType,
20801 int > = 0 >
20802 ValueType & get_to(ValueType& v) const noexcept(noexcept(
20803 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20804 {
20805 JSONSerializer<ValueType>::from_json(*this, v);
20806 return v;
20807 }
20808
20809 // specialization to allow to call get_to with a basic_json value
20810 // see https://github.com/nlohmann/json/issues/2175
20811 template<typename ValueType,
20814 int> = 0>
20815 ValueType & get_to(ValueType& v) const
20816 {
20817 v = *this;
20818 return v;
20819 }
20820
20821 template <
20822 typename T, std::size_t N,
20823 typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20826 Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20827 noexcept(noexcept(JSONSerializer<Array>::from_json(
20828 std::declval<const basic_json_t&>(), v)))
20829 {
20830 JSONSerializer<Array>::from_json(*this, v);
20831 return v;
20832 }
20833
20860 template<typename ReferenceType, typename std::enable_if<
20861 std::is_reference<ReferenceType>::value, int>::type = 0>
20862 ReferenceType get_ref()
20863 {
20864 // delegate call to get_ref_impl
20865 return get_ref_impl<ReferenceType>(*this);
20866 }
20867
20872 template < typename ReferenceType, typename std::enable_if <
20873 std::is_reference<ReferenceType>::value&&
20874 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
20875 ReferenceType get_ref() const
20876 {
20877 // delegate call to get_ref_impl
20878 return get_ref_impl<ReferenceType>(*this);
20879 }
20880
20910 template < typename ValueType, typename std::enable_if <
20917
20918#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20920#endif
20922 >::value, int >::type = 0 >
20923 JSON_EXPLICIT operator ValueType() const
20924 {
20925 // delegate the call to get<>() const
20926 return get<ValueType>();
20927 }
20928
20939 {
20940 if (!is_binary())
20941 {
20942 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20943 }
20944
20945 return *get_ptr<binary_t*>();
20946 }
20947
20949 const binary_t& get_binary() const
20950 {
20951 if (!is_binary())
20952 {
20953 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20954 }
20955
20956 return *get_ptr<const binary_t*>();
20957 }
20958
20960
20961
20963 // element access //
20965
20969
20997 {
20998 // at only works for arrays
21000 {
21001 JSON_TRY
21002 {
21003 return set_parent(m_value.array->at(idx));
21004 }
21005 JSON_CATCH (std::out_of_range&)
21006 {
21007 // create better exception explanation
21008 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21009 }
21010 }
21011 else
21012 {
21013 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21014 }
21015 }
21016
21044 {
21045 // at only works for arrays
21047 {
21048 JSON_TRY
21049 {
21050 return m_value.array->at(idx);
21051 }
21052 JSON_CATCH (std::out_of_range&)
21053 {
21054 // create better exception explanation
21055 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21056 }
21057 }
21058 else
21059 {
21060 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21061 }
21062 }
21063
21094 reference at(const typename object_t::key_type& key)
21095 {
21096 // at only works for objects
21098 {
21099 JSON_TRY
21100 {
21101 return set_parent(m_value.object->at(key));
21102 }
21103 JSON_CATCH (std::out_of_range&)
21104 {
21105 // create better exception explanation
21106 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21107 }
21108 }
21109 else
21110 {
21111 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21112 }
21113 }
21114
21145 const_reference at(const typename object_t::key_type& key) const
21146 {
21147 // at only works for objects
21149 {
21150 JSON_TRY
21151 {
21152 return m_value.object->at(key);
21153 }
21154 JSON_CATCH (std::out_of_range&)
21155 {
21156 // create better exception explanation
21157 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21158 }
21159 }
21160 else
21161 {
21162 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21163 }
21164 }
21165
21192 {
21193 // implicitly convert null value to an empty array
21194 if (is_null())
21195 {
21196 m_type = value_t::array;
21197 m_value.array = create<array_t>();
21199 }
21200
21201 // operator[] only works for arrays
21203 {
21204 // fill up array with null values if given idx is outside range
21205 if (idx >= m_value.array->size())
21206 {
21207#if JSON_DIAGNOSTICS
21208 // remember array size & capacity before resizing
21209 const auto old_size = m_value.array->size();
21210 const auto old_capacity = m_value.array->capacity();
21211#endif
21212 m_value.array->resize(idx + 1);
21213
21214#if JSON_DIAGNOSTICS
21215 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
21216 {
21217 // capacity has changed: update all parents
21218 set_parents();
21219 }
21220 else
21221 {
21222 // set parent for values added above
21223 set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
21224 }
21225#endif
21227 }
21228
21229 return m_value.array->operator[](idx);
21230 }
21231
21232 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21233 }
21234
21255 {
21256 // const operator[] only works for arrays
21258 {
21259 return m_value.array->operator[](idx);
21260 }
21261
21262 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21263 }
21264
21292 reference operator[](const typename object_t::key_type& key)
21293 {
21294 // implicitly convert null value to an empty object
21295 if (is_null())
21296 {
21297 m_type = value_t::object;
21298 m_value.object = create<object_t>();
21300 }
21301
21302 // operator[] only works for objects
21304 {
21305 return set_parent(m_value.object->operator[](key));
21306 }
21307
21308 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21309 }
21310
21341 const_reference operator[](const typename object_t::key_type& key) const
21342 {
21343 // const operator[] only works for objects
21345 {
21346 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21347 return m_value.object->find(key)->second;
21348 }
21349
21350 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21351 }
21352
21380 template<typename T>
21382 reference operator[](T* key)
21383 {
21384 // implicitly convert null to object
21385 if (is_null())
21386 {
21387 m_type = value_t::object;
21388 m_value = value_t::object;
21390 }
21391
21392 // at only works for objects
21394 {
21395 return set_parent(m_value.object->operator[](key));
21396 }
21397
21398 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21399 }
21400
21431 template<typename T>
21433 const_reference operator[](T* key) const
21434 {
21435 // at only works for objects
21437 {
21438 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21439 return m_value.object->find(key)->second;
21440 }
21441
21442 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21443 }
21444
21495 // using std::is_convertible in a std::enable_if will fail when using explicit conversions
21496 template < class ValueType, typename std::enable_if <
21498 && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
21499 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21500 {
21501 // at only works for objects
21503 {
21504 // if key is found, return value and given default value otherwise
21505 const auto it = find(key);
21506 if (it != end())
21507 {
21508 return it->template get<ValueType>();
21509 }
21510
21511 return default_value;
21512 }
21513
21514 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21515 }
21516
21521 string_t value(const typename object_t::key_type& key, const char* default_value) const
21522 {
21523 return value(key, string_t(default_value));
21524 }
21525
21569 template<class ValueType, typename std::enable_if<
21571 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21572 {
21573 // at only works for objects
21575 {
21576 // if pointer resolves a value, return it or use default value
21577 JSON_TRY
21578 {
21579 return ptr.get_checked(this).template get<ValueType>();
21580 }
21582 {
21583 return default_value;
21584 }
21585 }
21586
21587 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21588 }
21589
21595 string_t value(const json_pointer& ptr, const char* default_value) const
21596 {
21597 return value(ptr, string_t(default_value));
21598 }
21599
21626 {
21627 return *begin();
21628 }
21629
21634 {
21635 return *cbegin();
21636 }
21637
21670 {
21671 auto tmp = end();
21672 --tmp;
21673 return *tmp;
21674 }
21675
21680 {
21681 auto tmp = cend();
21682 --tmp;
21683 return *tmp;
21684 }
21685
21732 template < class IteratorType, typename std::enable_if <
21733 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21734 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21735 = 0 >
21736 IteratorType erase(IteratorType pos)
21737 {
21738 // make sure iterator fits the current value
21739 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21740 {
21741 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
21742 }
21743
21744 IteratorType result = end();
21745
21746 switch (m_type)
21747 {
21748 case value_t::boolean:
21749 case value_t::number_float:
21750 case value_t::number_integer:
21751 case value_t::number_unsigned:
21752 case value_t::string:
21753 case value_t::binary:
21754 {
21755 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21756 {
21757 JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
21758 }
21759
21760 if (is_string())
21761 {
21762 AllocatorType<string_t> alloc;
21763 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21764 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21765 m_value.string = nullptr;
21766 }
21767 else if (is_binary())
21768 {
21769 AllocatorType<binary_t> alloc;
21770 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21771 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21772 m_value.binary = nullptr;
21773 }
21774
21775 m_type = value_t::null;
21777 break;
21778 }
21779
21780 case value_t::object:
21781 {
21782 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
21783 break;
21784 }
21785
21786 case value_t::array:
21787 {
21788 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
21789 break;
21790 }
21791
21792 case value_t::null:
21793 case value_t::discarded:
21794 default:
21795 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21796 }
21797
21798 return result;
21799 }
21800
21847 template < class IteratorType, typename std::enable_if <
21848 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21849 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21850 = 0 >
21851 IteratorType erase(IteratorType first, IteratorType last)
21852 {
21853 // make sure iterator fits the current value
21854 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21855 {
21856 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
21857 }
21858
21859 IteratorType result = end();
21860
21861 switch (m_type)
21862 {
21863 case value_t::boolean:
21864 case value_t::number_float:
21865 case value_t::number_integer:
21866 case value_t::number_unsigned:
21867 case value_t::string:
21868 case value_t::binary:
21869 {
21870 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21871 || !last.m_it.primitive_iterator.is_end()))
21872 {
21873 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
21874 }
21875
21876 if (is_string())
21877 {
21878 AllocatorType<string_t> alloc;
21879 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21880 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21881 m_value.string = nullptr;
21882 }
21883 else if (is_binary())
21884 {
21885 AllocatorType<binary_t> alloc;
21886 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21887 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21888 m_value.binary = nullptr;
21889 }
21890
21891 m_type = value_t::null;
21893 break;
21894 }
21895
21896 case value_t::object:
21897 {
21898 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
21899 last.m_it.object_iterator);
21900 break;
21901 }
21902
21903 case value_t::array:
21904 {
21905 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
21906 last.m_it.array_iterator);
21907 break;
21908 }
21909
21910 case value_t::null:
21911 case value_t::discarded:
21912 default:
21913 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21914 }
21915
21916 return result;
21917 }
21918
21948 size_type erase(const typename object_t::key_type& key)
21949 {
21950 // this erase only works for objects
21952 {
21953 return m_value.object->erase(key);
21954 }
21955
21956 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21957 }
21958
21983 void erase(const size_type idx)
21984 {
21985 // this erase only works for arrays
21987 {
21988 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21989 {
21990 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21991 }
21992
21993 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21994 }
21995 else
21996 {
21997 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21998 }
21999 }
22000
22002
22003
22005 // lookup //
22007
22010
22035 template<typename KeyT>
22036 iterator find(KeyT&& key)
22037 {
22038 auto result = end();
22039
22040 if (is_object())
22041 {
22042 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
22043 }
22044
22045 return result;
22046 }
22047
22052 template<typename KeyT>
22053 const_iterator find(KeyT&& key) const
22054 {
22055 auto result = cend();
22056
22057 if (is_object())
22058 {
22059 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
22060 }
22061
22062 return result;
22063 }
22064
22086 template<typename KeyT>
22087 size_type count(KeyT&& key) const
22088 {
22089 // return 0 for all nonobject types
22090 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
22091 }
22092
22118 template < typename KeyT, typename std::enable_if <
22119 !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
22120 bool contains(KeyT && key) const
22121 {
22122 return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
22123 }
22124
22151 bool contains(const json_pointer& ptr) const
22152 {
22153 return ptr.contains(this);
22154 }
22155
22157
22158
22160 // iterators //
22162
22165
22190 iterator begin() noexcept
22191 {
22192 iterator result(this);
22193 result.set_begin();
22194 return result;
22195 }
22196
22200 const_iterator begin() const noexcept
22201 {
22202 return cbegin();
22203 }
22204
22230 const_iterator cbegin() const noexcept
22231 {
22232 const_iterator result(this);
22233 result.set_begin();
22234 return result;
22235 }
22236
22261 iterator end() noexcept
22262 {
22263 iterator result(this);
22264 result.set_end();
22265 return result;
22266 }
22267
22271 const_iterator end() const noexcept
22272 {
22273 return cend();
22274 }
22275
22301 const_iterator cend() const noexcept
22302 {
22303 const_iterator result(this);
22304 result.set_end();
22305 return result;
22306 }
22307
22332 {
22333 return reverse_iterator(end());
22334 }
22335
22340 {
22341 return crbegin();
22342 }
22343
22369 {
22370 return reverse_iterator(begin());
22371 }
22372
22377 {
22378 return crend();
22379 }
22380
22406 {
22407 return const_reverse_iterator(cend());
22408 }
22409
22435 {
22437 }
22438
22439 public:
22499 {
22500 return ref.items();
22501 }
22502
22508 {
22509 return ref.items();
22510 }
22511
22581 {
22582 return iteration_proxy<iterator>(*this);
22583 }
22584
22589 {
22590 return iteration_proxy<const_iterator>(*this);
22591 }
22592
22594
22595
22597 // capacity //
22599
22602
22645 bool empty() const noexcept
22646 {
22647 switch (m_type)
22648 {
22649 case value_t::null:
22650 {
22651 // null values are empty
22652 return true;
22653 }
22654
22655 case value_t::array:
22656 {
22657 // delegate call to array_t::empty()
22658 return m_value.array->empty();
22659 }
22660
22661 case value_t::object:
22662 {
22663 // delegate call to object_t::empty()
22664 return m_value.object->empty();
22665 }
22666
22667 case value_t::string:
22668 case value_t::boolean:
22669 case value_t::number_integer:
22670 case value_t::number_unsigned:
22671 case value_t::number_float:
22672 case value_t::binary:
22673 case value_t::discarded:
22674 default:
22675 {
22676 // all other types are nonempty
22677 return false;
22678 }
22679 }
22680 }
22681
22725 size_type size() const noexcept
22726 {
22727 switch (m_type)
22728 {
22729 case value_t::null:
22730 {
22731 // null values are empty
22732 return 0;
22733 }
22734
22735 case value_t::array:
22736 {
22737 // delegate call to array_t::size()
22738 return m_value.array->size();
22739 }
22740
22741 case value_t::object:
22742 {
22743 // delegate call to object_t::size()
22744 return m_value.object->size();
22745 }
22746
22747 case value_t::string:
22748 case value_t::boolean:
22749 case value_t::number_integer:
22750 case value_t::number_unsigned:
22751 case value_t::number_float:
22752 case value_t::binary:
22753 case value_t::discarded:
22754 default:
22755 {
22756 // all other types have size 1
22757 return 1;
22758 }
22759 }
22760 }
22761
22803 size_type max_size() const noexcept
22804 {
22805 switch (m_type)
22806 {
22807 case value_t::array:
22808 {
22809 // delegate call to array_t::max_size()
22810 return m_value.array->max_size();
22811 }
22812
22813 case value_t::object:
22814 {
22815 // delegate call to object_t::max_size()
22816 return m_value.object->max_size();
22817 }
22818
22819 case value_t::null:
22820 case value_t::string:
22821 case value_t::boolean:
22822 case value_t::number_integer:
22823 case value_t::number_unsigned:
22824 case value_t::number_float:
22825 case value_t::binary:
22826 case value_t::discarded:
22827 default:
22828 {
22829 // all other types have max_size() == size()
22830 return size();
22831 }
22832 }
22833 }
22834
22836
22837
22839 // modifiers //
22841
22844
22882 void clear() noexcept
22883 {
22884 switch (m_type)
22885 {
22886 case value_t::number_integer:
22887 {
22888 m_value.number_integer = 0;
22889 break;
22890 }
22891
22892 case value_t::number_unsigned:
22893 {
22894 m_value.number_unsigned = 0;
22895 break;
22896 }
22897
22898 case value_t::number_float:
22899 {
22900 m_value.number_float = 0.0;
22901 break;
22902 }
22903
22904 case value_t::boolean:
22905 {
22906 m_value.boolean = false;
22907 break;
22908 }
22909
22910 case value_t::string:
22911 {
22912 m_value.string->clear();
22913 break;
22914 }
22915
22916 case value_t::binary:
22917 {
22918 m_value.binary->clear();
22919 break;
22920 }
22921
22922 case value_t::array:
22923 {
22924 m_value.array->clear();
22925 break;
22926 }
22927
22928 case value_t::object:
22929 {
22930 m_value.object->clear();
22931 break;
22932 }
22933
22934 case value_t::null:
22935 case value_t::discarded:
22936 default:
22937 break;
22938 }
22939 }
22940
22962 {
22963 // push_back only works for null objects or arrays
22964 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22965 {
22966 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22967 }
22968
22969 // transform null object into an array
22970 if (is_null())
22971 {
22972 m_type = value_t::array;
22973 m_value = value_t::array;
22975 }
22976
22977 // add element to array (move semantics)
22978 const auto old_capacity = m_value.array->capacity();
22979 m_value.array->push_back(std::move(val));
22980 set_parent(m_value.array->back(), old_capacity);
22981 // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
22982 }
22983
22989 {
22990 push_back(std::move(val));
22991 return *this;
22992 }
22993
22998 void push_back(const basic_json& val)
22999 {
23000 // push_back only works for null objects or arrays
23001 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23002 {
23003 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
23004 }
23005
23006 // transform null object into an array
23007 if (is_null())
23008 {
23009 m_type = value_t::array;
23010 m_value = value_t::array;
23012 }
23013
23014 // add element to array
23015 const auto old_capacity = m_value.array->capacity();
23016 m_value.array->push_back(val);
23017 set_parent(m_value.array->back(), old_capacity);
23018 }
23019
23025 {
23026 push_back(val);
23027 return *this;
23028 }
23029
23050 void push_back(const typename object_t::value_type& val)
23051 {
23052 // push_back only works for null objects or objects
23053 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23054 {
23055 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
23056 }
23057
23058 // transform null object into an object
23059 if (is_null())
23060 {
23061 m_type = value_t::object;
23062 m_value = value_t::object;
23064 }
23065
23066 // add element to object
23067 auto res = m_value.object->insert(val);
23068 set_parent(res.first->second);
23069 }
23070
23075 reference operator+=(const typename object_t::value_type& val)
23076 {
23077 push_back(val);
23078 return *this;
23079 }
23080
23107 {
23108 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
23109 {
23110 basic_json&& key = init.begin()->moved_or_copied();
23111 push_back(typename object_t::value_type(
23112 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
23113 }
23114 else
23115 {
23116 push_back(basic_json(init));
23117 }
23118 }
23119
23125 {
23126 push_back(init);
23127 return *this;
23128 }
23129
23153 template<class... Args>
23154 reference emplace_back(Args&& ... args)
23155 {
23156 // emplace_back only works for null objects or arrays
23157 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23158 {
23159 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
23160 }
23161
23162 // transform null object into an array
23163 if (is_null())
23164 {
23165 m_type = value_t::array;
23166 m_value = value_t::array;
23168 }
23169
23170 // add element to array (perfect forwarding)
23171 const auto old_capacity = m_value.array->capacity();
23172 m_value.array->emplace_back(std::forward<Args>(args)...);
23173 return set_parent(m_value.array->back(), old_capacity);
23174 }
23175
23203 template<class... Args>
23204 std::pair<iterator, bool> emplace(Args&& ... args)
23205 {
23206 // emplace only works for null objects or arrays
23207 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23208 {
23209 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
23210 }
23211
23212 // transform null object into an object
23213 if (is_null())
23214 {
23215 m_type = value_t::object;
23216 m_value = value_t::object;
23218 }
23219
23220 // add element to array (perfect forwarding)
23221 auto res = m_value.object->emplace(std::forward<Args>(args)...);
23222 set_parent(res.first->second);
23223
23224 // create result iterator and set iterator to the result of emplace
23225 auto it = begin();
23226 it.m_it.object_iterator = res.first;
23227
23228 // return pair of iterator and boolean
23229 return {it, res.second};
23230 }
23231
23235 template<typename... Args>
23237 {
23238 iterator result(this);
23239 JSON_ASSERT(m_value.array != nullptr);
23240
23241 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
23242 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
23243 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
23244
23245 // This could have been written as:
23246 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
23247 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
23248
23249 set_parents();
23250 return result;
23251 }
23252
23276 {
23277 // insert only works for arrays
23279 {
23280 // check if iterator pos fits to this JSON value
23281 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23282 {
23283 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23284 }
23285
23286 // insert to array and return iterator
23287 return insert_iterator(pos, val);
23288 }
23289
23290 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23291 }
23292
23298 {
23299 return insert(pos, val);
23300 }
23301
23327 {
23328 // insert only works for arrays
23330 {
23331 // check if iterator pos fits to this JSON value
23332 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23333 {
23334 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23335 }
23336
23337 // insert to array and return iterator
23338 return insert_iterator(pos, cnt, val);
23339 }
23340
23341 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23342 }
23343
23375 {
23376 // insert only works for arrays
23378 {
23379 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23380 }
23381
23382 // check if iterator pos fits to this JSON value
23383 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23384 {
23385 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23386 }
23387
23388 // check if range iterators belong to the same JSON object
23389 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23390 {
23391 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23392 }
23393
23394 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
23395 {
23396 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
23397 }
23398
23399 // insert to array and return iterator
23400 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
23401 }
23402
23428 {
23429 // insert only works for arrays
23431 {
23432 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23433 }
23434
23435 // check if iterator pos fits to this JSON value
23436 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23437 {
23438 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23439 }
23440
23441 // insert to array and return iterator
23442 return insert_iterator(pos, ilist.begin(), ilist.end());
23443 }
23444
23469 {
23470 // insert only works for objects
23472 {
23473 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23474 }
23475
23476 // check if range iterators belong to the same JSON object
23477 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23478 {
23479 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23480 }
23481
23482 // passed iterators must belong to objects
23483 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23484 {
23485 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23486 }
23487
23488 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
23489 }
23490
23513 void update(const_reference j, bool merge_objects = false)
23514 {
23515 update(j.begin(), j.end(), merge_objects);
23516 }
23517
23546 void update(const_iterator first, const_iterator last, bool merge_objects = false)
23547 {
23548 // implicitly convert null value to an empty object
23549 if (is_null())
23550 {
23551 m_type = value_t::object;
23552 m_value.object = create<object_t>();
23554 }
23555
23557 {
23558 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23559 }
23560
23561 // check if range iterators belong to the same JSON object
23562 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23563 {
23564 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23565 }
23566
23567 // passed iterators must belong to objects
23568 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23569 {
23570 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(first.m_object->type_name()), *first.m_object));
23571 }
23572
23573 for (auto it = first; it != last; ++it)
23574 {
23575 if (merge_objects && it.value().is_object())
23576 {
23577 auto it2 = m_value.object->find(it.key());
23578 if (it2 != m_value.object->end())
23579 {
23580 it2->second.update(it.value(), true);
23581 continue;
23582 }
23583 }
23584 m_value.object->operator[](it.key()) = it.value();
23585#if JSON_DIAGNOSTICS
23586 m_value.object->operator[](it.key()).m_parent = this;
23587#endif
23588 }
23589 }
23590
23608 void swap(reference other) noexcept (
23609 std::is_nothrow_move_constructible<value_t>::value&&
23610 std::is_nothrow_move_assignable<value_t>::value&&
23611 std::is_nothrow_move_constructible<json_value>::value&&
23612 std::is_nothrow_move_assignable<json_value>::value
23613 )
23614 {
23615 std::swap(m_type, other.m_type);
23616 std::swap(m_value, other.m_value);
23617
23618 set_parents();
23619 other.set_parents();
23621 }
23622
23641 friend void swap(reference left, reference right) noexcept (
23642 std::is_nothrow_move_constructible<value_t>::value&&
23643 std::is_nothrow_move_assignable<value_t>::value&&
23644 std::is_nothrow_move_constructible<json_value>::value&&
23645 std::is_nothrow_move_assignable<json_value>::value
23646 )
23647 {
23648 left.swap(right);
23649 }
23650
23671 void swap(array_t& other) // NOLINT(bugprone-exception-escape)
23672 {
23673 // swap only works for arrays
23675 {
23676 std::swap(*(m_value.array), other);
23677 }
23678 else
23679 {
23680 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23681 }
23682 }
23683
23704 void swap(object_t& other) // NOLINT(bugprone-exception-escape)
23705 {
23706 // swap only works for objects
23708 {
23709 std::swap(*(m_value.object), other);
23710 }
23711 else
23712 {
23713 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23714 }
23715 }
23716
23737 void swap(string_t& other) // NOLINT(bugprone-exception-escape)
23738 {
23739 // swap only works for strings
23741 {
23742 std::swap(*(m_value.string), other);
23743 }
23744 else
23745 {
23746 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23747 }
23748 }
23749
23770 void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
23771 {
23772 // swap only works for strings
23774 {
23775 std::swap(*(m_value.binary), other);
23776 }
23777 else
23778 {
23779 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23780 }
23781 }
23782
23784 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
23785 {
23786 // swap only works for strings
23788 {
23789 std::swap(*(m_value.binary), other);
23790 }
23791 else
23792 {
23793 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23794 }
23795 }
23796
23798
23799 public:
23801 // lexicographical comparison operators //
23803
23806
23862 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23863 {
23864#ifdef __GNUC__
23865#pragma GCC diagnostic push
23866#pragma GCC diagnostic ignored "-Wfloat-equal"
23867#endif
23868 const auto lhs_type = lhs.type();
23869 const auto rhs_type = rhs.type();
23870
23871 if (lhs_type == rhs_type)
23872 {
23873 switch (lhs_type)
23874 {
23875 case value_t::array:
23876 return *lhs.m_value.array == *rhs.m_value.array;
23877
23878 case value_t::object:
23879 return *lhs.m_value.object == *rhs.m_value.object;
23880
23881 case value_t::null:
23882 return true;
23883
23884 case value_t::string:
23885 return *lhs.m_value.string == *rhs.m_value.string;
23886
23887 case value_t::boolean:
23888 return lhs.m_value.boolean == rhs.m_value.boolean;
23889
23890 case value_t::number_integer:
23891 return lhs.m_value.number_integer == rhs.m_value.number_integer;
23892
23893 case value_t::number_unsigned:
23894 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
23895
23896 case value_t::number_float:
23897 return lhs.m_value.number_float == rhs.m_value.number_float;
23898
23899 case value_t::binary:
23900 return *lhs.m_value.binary == *rhs.m_value.binary;
23901
23902 case value_t::discarded:
23903 default:
23904 return false;
23905 }
23906 }
23907 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23908 {
23909 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
23910 }
23911 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23912 {
23913 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
23914 }
23915 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23916 {
23917 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
23918 }
23919 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23920 {
23921 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
23922 }
23923 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23924 {
23925 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
23926 }
23927 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23928 {
23929 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23930 }
23931
23932 return false;
23933#ifdef __GNUC__
23934#pragma GCC diagnostic pop
23935#endif
23936 }
23937
23942 template<typename ScalarType, typename std::enable_if<
23943 std::is_scalar<ScalarType>::value, int>::type = 0>
23944 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23945 {
23946 return lhs == basic_json(rhs);
23947 }
23948
23953 template<typename ScalarType, typename std::enable_if<
23954 std::is_scalar<ScalarType>::value, int>::type = 0>
23955 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23956 {
23957 return basic_json(lhs) == rhs;
23958 }
23959
23978 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23979 {
23980 return !(lhs == rhs);
23981 }
23982
23987 template<typename ScalarType, typename std::enable_if<
23988 std::is_scalar<ScalarType>::value, int>::type = 0>
23989 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23990 {
23991 return lhs != basic_json(rhs);
23992 }
23993
23998 template<typename ScalarType, typename std::enable_if<
23999 std::is_scalar<ScalarType>::value, int>::type = 0>
24000 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
24001 {
24002 return basic_json(lhs) != rhs;
24003 }
24004
24031 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
24032 {
24033 const auto lhs_type = lhs.type();
24034 const auto rhs_type = rhs.type();
24035
24036 if (lhs_type == rhs_type)
24037 {
24038 switch (lhs_type)
24039 {
24040 case value_t::array:
24041 // note parentheses are necessary, see
24042 // https://github.com/nlohmann/json/issues/1530
24043 return (*lhs.m_value.array) < (*rhs.m_value.array);
24044
24045 case value_t::object:
24046 return (*lhs.m_value.object) < (*rhs.m_value.object);
24047
24048 case value_t::null:
24049 return false;
24050
24051 case value_t::string:
24052 return (*lhs.m_value.string) < (*rhs.m_value.string);
24053
24054 case value_t::boolean:
24055 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
24056
24057 case value_t::number_integer:
24058 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
24059
24060 case value_t::number_unsigned:
24061 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
24062
24063 case value_t::number_float:
24064 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
24065
24066 case value_t::binary:
24067 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
24068
24069 case value_t::discarded:
24070 default:
24071 return false;
24072 }
24073 }
24074 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
24075 {
24076 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
24077 }
24078 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
24079 {
24080 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
24081 }
24082 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
24083 {
24084 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
24085 }
24086 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
24087 {
24088 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
24089 }
24090 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
24091 {
24092 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
24093 }
24094 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
24095 {
24096 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
24097 }
24098
24099 // We only reach this line if we cannot compare values. In that case,
24100 // we compare types. Note we have to call the operator explicitly,
24101 // because MSVC has problems otherwise.
24102 return operator<(lhs_type, rhs_type);
24103 }
24104
24109 template<typename ScalarType, typename std::enable_if<
24110 std::is_scalar<ScalarType>::value, int>::type = 0>
24111 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
24112 {
24113 return lhs < basic_json(rhs);
24114 }
24115
24120 template<typename ScalarType, typename std::enable_if<
24121 std::is_scalar<ScalarType>::value, int>::type = 0>
24122 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
24123 {
24124 return basic_json(lhs) < rhs;
24125 }
24126
24146 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
24147 {
24148 return !(rhs < lhs);
24149 }
24150
24155 template<typename ScalarType, typename std::enable_if<
24156 std::is_scalar<ScalarType>::value, int>::type = 0>
24157 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
24158 {
24159 return lhs <= basic_json(rhs);
24160 }
24161
24166 template<typename ScalarType, typename std::enable_if<
24167 std::is_scalar<ScalarType>::value, int>::type = 0>
24168 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
24169 {
24170 return basic_json(lhs) <= rhs;
24171 }
24172
24192 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
24193 {
24194 return !(lhs <= rhs);
24195 }
24196
24201 template<typename ScalarType, typename std::enable_if<
24202 std::is_scalar<ScalarType>::value, int>::type = 0>
24203 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
24204 {
24205 return lhs > basic_json(rhs);
24206 }
24207
24212 template<typename ScalarType, typename std::enable_if<
24213 std::is_scalar<ScalarType>::value, int>::type = 0>
24214 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
24215 {
24216 return basic_json(lhs) > rhs;
24217 }
24218
24238 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
24239 {
24240 return !(lhs < rhs);
24241 }
24242
24247 template<typename ScalarType, typename std::enable_if<
24248 std::is_scalar<ScalarType>::value, int>::type = 0>
24249 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
24250 {
24251 return lhs >= basic_json(rhs);
24252 }
24253
24258 template<typename ScalarType, typename std::enable_if<
24259 std::is_scalar<ScalarType>::value, int>::type = 0>
24260 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
24261 {
24262 return basic_json(lhs) >= rhs;
24263 }
24264
24266
24268 // serialization //
24270
24273#ifndef JSON_NO_IO
24305 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
24306 {
24307 // read width member and use it as indentation parameter if nonzero
24308 const bool pretty_print = o.width() > 0;
24309 const auto indentation = pretty_print ? o.width() : 0;
24310
24311 // reset width to 0 for subsequent calls to this stream
24312 o.width(0);
24313
24314 // do the actual serialization
24315 serializer s(detail::output_adapter<char>(o), o.fill());
24316 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
24317 return o;
24318 }
24319
24328 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
24329 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
24330 {
24331 return o << j;
24332 }
24333#endif // JSON_NO_IO
24335
24336
24338 // deserialization //
24340
24343
24395 template<typename InputType>
24397 static basic_json parse(InputType&& i,
24398 const parser_callback_t cb = nullptr,
24399 const bool allow_exceptions = true,
24400 const bool ignore_comments = false)
24401 {
24402 basic_json result;
24403 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
24404 return result;
24405 }
24406
24433 template<typename IteratorType>
24435 static basic_json parse(IteratorType first,
24436 IteratorType last,
24437 const parser_callback_t cb = nullptr,
24438 const bool allow_exceptions = true,
24439 const bool ignore_comments = false)
24440 {
24441 basic_json result;
24442 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
24443 return result;
24444 }
24445
24447 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
24448 static basic_json parse(detail::span_input_adapter&& i,
24449 const parser_callback_t cb = nullptr,
24450 const bool allow_exceptions = true,
24451 const bool ignore_comments = false)
24452 {
24453 basic_json result;
24454 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
24455 return result;
24456 }
24457
24488 template<typename InputType>
24489 static bool accept(InputType&& i,
24490 const bool ignore_comments = false)
24491 {
24492 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
24493 }
24494
24495 template<typename IteratorType>
24496 static bool accept(IteratorType first, IteratorType last,
24497 const bool ignore_comments = false)
24498 {
24499 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
24500 }
24501
24503 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
24504 static bool accept(detail::span_input_adapter&& i,
24505 const bool ignore_comments = false)
24506 {
24507 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
24508 }
24509
24550 template <typename InputType, typename SAX>
24552 static bool sax_parse(InputType&& i, SAX* sax,
24554 const bool strict = true,
24555 const bool ignore_comments = false)
24556 {
24557 auto ia = detail::input_adapter(std::forward<InputType>(i));
24558 return format == input_format_t::json
24559 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24560 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24561 }
24562
24563 template<class IteratorType, class SAX>
24565 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
24567 const bool strict = true,
24568 const bool ignore_comments = false)
24569 {
24570 auto ia = detail::input_adapter(std::move(first), std::move(last));
24571 return format == input_format_t::json
24572 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24573 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24574 }
24575
24576 template <typename SAX>
24577 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
24579 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
24581 const bool strict = true,
24582 const bool ignore_comments = false)
24583 {
24584 auto ia = i.get();
24585 return format == input_format_t::json
24586 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24587 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24588 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24589 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24590 }
24591#ifndef JSON_NO_IO
24600 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
24601 friend std::istream& operator<<(basic_json& j, std::istream& i)
24602 {
24603 return operator>>(i, j);
24604 }
24605
24631 friend std::istream& operator>>(std::istream& i, basic_json& j)
24632 {
24633 parser(detail::input_adapter(i)).parse(false, j);
24634 return i;
24635 }
24636#endif // JSON_NO_IO
24638
24640 // convenience functions //
24642
24675 const char* type_name() const noexcept
24676 {
24677 {
24678 switch (m_type)
24679 {
24680 case value_t::null:
24681 return "null";
24682 case value_t::object:
24683 return "object";
24684 case value_t::array:
24685 return "array";
24686 case value_t::string:
24687 return "string";
24688 case value_t::boolean:
24689 return "boolean";
24690 case value_t::binary:
24691 return "binary";
24692 case value_t::discarded:
24693 return "discarded";
24694 case value_t::number_integer:
24695 case value_t::number_unsigned:
24696 case value_t::number_float:
24697 default:
24698 return "number";
24699 }
24700 }
24701 }
24702
24703
24706 // member variables //
24708
24710 value_t m_type = value_t::null;
24711
24714
24715#if JSON_DIAGNOSTICS
24717 basic_json* m_parent = nullptr;
24718#endif
24719
24721 // binary serialization/deserialization //
24723
24726
24727 public:
24826 static std::vector<std::uint8_t> to_cbor(const basic_json& j)
24827 {
24828 std::vector<std::uint8_t> result;
24829 to_cbor(j, result);
24830 return result;
24831 }
24832
24834 {
24836 }
24837
24839 {
24841 }
24842
24921 static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
24922 {
24923 std::vector<std::uint8_t> result;
24924 to_msgpack(j, result);
24925 return result;
24926 }
24927
24929 {
24931 }
24932
24934 {
24936 }
24937
25024 static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
25025 const bool use_size = false,
25026 const bool use_type = false)
25027 {
25028 std::vector<std::uint8_t> result;
25029 to_ubjson(j, result, use_size, use_type);
25030 return result;
25031 }
25032
25034 const bool use_size = false, const bool use_type = false)
25035 {
25036 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
25037 }
25038
25040 const bool use_size = false, const bool use_type = false)
25041 {
25042 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
25043 }
25044
25045
25102 static std::vector<std::uint8_t> to_bson(const basic_json& j)
25103 {
25104 std::vector<std::uint8_t> result;
25105 to_bson(j, result);
25106 return result;
25107 }
25108
25118 {
25120 }
25121
25126 {
25128 }
25129
25130
25233 template<typename InputType>
25235 static basic_json from_cbor(InputType&& i,
25236 const bool strict = true,
25237 const bool allow_exceptions = true,
25238 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25239 {
25240 basic_json result;
25241 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25242 auto ia = detail::input_adapter(std::forward<InputType>(i));
25243 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25244 return res ? result : basic_json(value_t::discarded);
25245 }
25246
25250 template<typename IteratorType>
25252 static basic_json from_cbor(IteratorType first, IteratorType last,
25253 const bool strict = true,
25254 const bool allow_exceptions = true,
25255 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25256 {
25257 basic_json result;
25258 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25259 auto ia = detail::input_adapter(std::move(first), std::move(last));
25260 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25261 return res ? result : basic_json(value_t::discarded);
25262 }
25263
25264 template<typename T>
25266 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25267 static basic_json from_cbor(const T* ptr, std::size_t len,
25268 const bool strict = true,
25269 const bool allow_exceptions = true,
25270 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25271 {
25272 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
25273 }
25274
25275
25277 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25278 static basic_json from_cbor(detail::span_input_adapter&& i,
25279 const bool strict = true,
25280 const bool allow_exceptions = true,
25281 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25282 {
25283 basic_json result;
25284 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25285 auto ia = i.get();
25286 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25287 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25288 return res ? result : basic_json(value_t::discarded);
25289 }
25290
25377 template<typename InputType>
25379 static basic_json from_msgpack(InputType&& i,
25380 const bool strict = true,
25381 const bool allow_exceptions = true)
25382 {
25383 basic_json result;
25384 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25385 auto ia = detail::input_adapter(std::forward<InputType>(i));
25386 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25387 return res ? result : basic_json(value_t::discarded);
25388 }
25389
25393 template<typename IteratorType>
25395 static basic_json from_msgpack(IteratorType first, IteratorType last,
25396 const bool strict = true,
25397 const bool allow_exceptions = true)
25398 {
25399 basic_json result;
25400 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25401 auto ia = detail::input_adapter(std::move(first), std::move(last));
25402 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25403 return res ? result : basic_json(value_t::discarded);
25404 }
25405
25406
25407 template<typename T>
25409 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25410 static basic_json from_msgpack(const T* ptr, std::size_t len,
25411 const bool strict = true,
25412 const bool allow_exceptions = true)
25413 {
25414 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
25415 }
25416
25418 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25419 static basic_json from_msgpack(detail::span_input_adapter&& i,
25420 const bool strict = true,
25421 const bool allow_exceptions = true)
25422 {
25423 basic_json result;
25424 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25425 auto ia = i.get();
25426 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25427 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25428 return res ? result : basic_json(value_t::discarded);
25429 }
25430
25431
25494 template<typename InputType>
25496 static basic_json from_ubjson(InputType&& i,
25497 const bool strict = true,
25498 const bool allow_exceptions = true)
25499 {
25500 basic_json result;
25501 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25502 auto ia = detail::input_adapter(std::forward<InputType>(i));
25503 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25504 return res ? result : basic_json(value_t::discarded);
25505 }
25506
25510 template<typename IteratorType>
25512 static basic_json from_ubjson(IteratorType first, IteratorType last,
25513 const bool strict = true,
25514 const bool allow_exceptions = true)
25515 {
25516 basic_json result;
25517 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25518 auto ia = detail::input_adapter(std::move(first), std::move(last));
25519 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25520 return res ? result : basic_json(value_t::discarded);
25521 }
25522
25523 template<typename T>
25525 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25526 static basic_json from_ubjson(const T* ptr, std::size_t len,
25527 const bool strict = true,
25528 const bool allow_exceptions = true)
25529 {
25530 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
25531 }
25532
25534 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25535 static basic_json from_ubjson(detail::span_input_adapter&& i,
25536 const bool strict = true,
25537 const bool allow_exceptions = true)
25538 {
25539 basic_json result;
25540 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25541 auto ia = i.get();
25542 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25543 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25544 return res ? result : basic_json(value_t::discarded);
25545 }
25546
25547
25608 template<typename InputType>
25610 static basic_json from_bson(InputType&& i,
25611 const bool strict = true,
25612 const bool allow_exceptions = true)
25613 {
25614 basic_json result;
25615 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25616 auto ia = detail::input_adapter(std::forward<InputType>(i));
25617 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25618 return res ? result : basic_json(value_t::discarded);
25619 }
25620
25624 template<typename IteratorType>
25626 static basic_json from_bson(IteratorType first, IteratorType last,
25627 const bool strict = true,
25628 const bool allow_exceptions = true)
25629 {
25630 basic_json result;
25631 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25632 auto ia = detail::input_adapter(std::move(first), std::move(last));
25633 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25634 return res ? result : basic_json(value_t::discarded);
25635 }
25636
25637 template<typename T>
25639 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25640 static basic_json from_bson(const T* ptr, std::size_t len,
25641 const bool strict = true,
25642 const bool allow_exceptions = true)
25643 {
25644 return from_bson(ptr, ptr + len, strict, allow_exceptions);
25645 }
25646
25648 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25649 static basic_json from_bson(detail::span_input_adapter&& i,
25650 const bool strict = true,
25651 const bool allow_exceptions = true)
25652 {
25653 basic_json result;
25654 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25655 auto ia = i.get();
25656 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25657 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25658 return res ? result : basic_json(value_t::discarded);
25659 }
25661
25663 // JSON Pointer support //
25665
25668
25703 {
25704 return ptr.get_unchecked(this);
25705 }
25706
25731 {
25732 return ptr.get_unchecked(this);
25733 }
25734
25774 {
25775 return ptr.get_checked(this);
25776 }
25777
25817 {
25818 return ptr.get_checked(this);
25819 }
25820
25844 {
25845 basic_json result(value_t::object);
25846 json_pointer::flatten("", *this, result);
25847 return result;
25848 }
25849
25881 {
25882 return json_pointer::unflatten(*this);
25883 }
25884
25886
25888 // JSON Patch functions //
25890
25893
25941 basic_json patch(const basic_json& json_patch) const
25942 {
25943 // make a working copy to apply the patch to
25944 basic_json result = *this;
25945
25946 // the valid JSON Patch operations
25947 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
25948
25949 const auto get_op = [](const std::string & op)
25950 {
25951 if (op == "add")
25952 {
25953 return patch_operations::add;
25954 }
25955 if (op == "remove")
25956 {
25957 return patch_operations::remove;
25958 }
25959 if (op == "replace")
25960 {
25961 return patch_operations::replace;
25962 }
25963 if (op == "move")
25964 {
25965 return patch_operations::move;
25966 }
25967 if (op == "copy")
25968 {
25969 return patch_operations::copy;
25970 }
25971 if (op == "test")
25972 {
25973 return patch_operations::test;
25974 }
25975
25976 return patch_operations::invalid;
25977 };
25978
25979 // wrapper for "add" operation; add value at ptr
25980 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
25981 {
25982 // adding to the root of the target document means replacing it
25983 if (ptr.empty())
25984 {
25985 result = val;
25986 return;
25987 }
25988
25989 // make sure the top element of the pointer exists
25990 json_pointer top_pointer = ptr.top();
25991 if (top_pointer != ptr)
25992 {
25993 result.at(top_pointer);
25994 }
25995
25996 // get reference to parent of JSON pointer ptr
25997 const auto last_path = ptr.back();
25998 ptr.pop_back();
25999 basic_json& parent = result[ptr];
26000
26001 switch (parent.m_type)
26002 {
26003 case value_t::null:
26004 case value_t::object:
26005 {
26006 // use operator[] to add value
26007 parent[last_path] = val;
26008 break;
26009 }
26010
26011 case value_t::array:
26012 {
26013 if (last_path == "-")
26014 {
26015 // special case: append to back
26016 parent.push_back(val);
26017 }
26018 else
26019 {
26020 const auto idx = json_pointer::array_index(last_path);
26021 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
26022 {
26023 // avoid undefined behavior
26024 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
26025 }
26026
26027 // default case: insert add offset
26028 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
26029 }
26030 break;
26031 }
26032
26033 // if there exists a parent it cannot be primitive
26034 case value_t::string: // LCOV_EXCL_LINE
26035 case value_t::boolean: // LCOV_EXCL_LINE
26036 case value_t::number_integer: // LCOV_EXCL_LINE
26037 case value_t::number_unsigned: // LCOV_EXCL_LINE
26038 case value_t::number_float: // LCOV_EXCL_LINE
26039 case value_t::binary: // LCOV_EXCL_LINE
26040 case value_t::discarded: // LCOV_EXCL_LINE
26041 default: // LCOV_EXCL_LINE
26042 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
26043 }
26044 };
26045
26046 // wrapper for "remove" operation; remove value at ptr
26047 const auto operation_remove = [this, &result](json_pointer & ptr)
26048 {
26049 // get reference to parent of JSON pointer ptr
26050 const auto last_path = ptr.back();
26051 ptr.pop_back();
26052 basic_json& parent = result.at(ptr);
26053
26054 // remove child
26055 if (parent.is_object())
26056 {
26057 // perform range check
26058 auto it = parent.find(last_path);
26059 if (JSON_HEDLEY_LIKELY(it != parent.end()))
26060 {
26061 parent.erase(it);
26062 }
26063 else
26064 {
26065 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
26066 }
26067 }
26068 else if (parent.is_array())
26069 {
26070 // note erase performs range check
26071 parent.erase(json_pointer::array_index(last_path));
26072 }
26073 };
26074
26075 // type check: top level value must be an array
26076 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
26077 {
26078 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
26079 }
26080
26081 // iterate and apply the operations
26082 for (const auto& val : json_patch)
26083 {
26084 // wrapper to get a value for an operation
26085 const auto get_value = [&val](const std::string & op,
26086 const std::string & member,
26087 bool string_type) -> basic_json &
26088 {
26089 // find value
26090 auto it = val.m_value.object->find(member);
26091
26092 // context-sensitive error message
26093 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
26094
26095 // check if desired value is present
26096 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
26097 {
26098 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
26099 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
26100 }
26101
26102 // check if result is of type string
26103 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
26104 {
26105 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
26106 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
26107 }
26108
26109 // no error: return value
26110 return it->second;
26111 };
26112
26113 // type check: every element of the array must be an object
26114 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
26115 {
26116 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
26117 }
26118
26119 // collect mandatory members
26120 const auto op = get_value("op", "op", true).template get<std::string>();
26121 const auto path = get_value(op, "path", true).template get<std::string>();
26122 json_pointer ptr(path);
26123
26124 switch (get_op(op))
26125 {
26126 case patch_operations::add:
26127 {
26128 operation_add(ptr, get_value("add", "value", false));
26129 break;
26130 }
26131
26132 case patch_operations::remove:
26133 {
26134 operation_remove(ptr);
26135 break;
26136 }
26137
26138 case patch_operations::replace:
26139 {
26140 // the "path" location must exist - use at()
26141 result.at(ptr) = get_value("replace", "value", false);
26142 break;
26143 }
26144
26145 case patch_operations::move:
26146 {
26147 const auto from_path = get_value("move", "from", true).template get<std::string>();
26148 json_pointer from_ptr(from_path);
26149
26150 // the "from" location must exist - use at()
26151 basic_json v = result.at(from_ptr);
26152
26153 // The move operation is functionally identical to a
26154 // "remove" operation on the "from" location, followed
26155 // immediately by an "add" operation at the target
26156 // location with the value that was just removed.
26157 operation_remove(from_ptr);
26158 operation_add(ptr, v);
26159 break;
26160 }
26161
26162 case patch_operations::copy:
26163 {
26164 const auto from_path = get_value("copy", "from", true).template get<std::string>();
26165 const json_pointer from_ptr(from_path);
26166
26167 // the "from" location must exist - use at()
26168 basic_json v = result.at(from_ptr);
26169
26170 // The copy is functionally identical to an "add"
26171 // operation at the target location using the value
26172 // specified in the "from" member.
26173 operation_add(ptr, v);
26174 break;
26175 }
26176
26177 case patch_operations::test:
26178 {
26179 bool success = false;
26180 JSON_TRY
26181 {
26182 // check if "value" matches the one at "path"
26183 // the "path" location must exist - use at()
26184 success = (result.at(ptr) == get_value("test", "value", false));
26185 }
26187 {
26188 // ignore out of range errors: success remains false
26189 }
26190
26191 // throw an exception if test fails
26192 if (JSON_HEDLEY_UNLIKELY(!success))
26193 {
26194 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
26195 }
26196
26197 break;
26198 }
26199
26200 case patch_operations::invalid:
26201 default:
26202 {
26203 // op must be "add", "remove", "replace", "move", "copy", or
26204 // "test"
26205 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
26206 }
26207 }
26208 }
26209
26210 return result;
26211 }
26212
26247 static basic_json diff(const basic_json& source, const basic_json& target,
26248 const std::string& path = "")
26249 {
26250 // the patch
26251 basic_json result(value_t::array);
26252
26253 // if the values are the same, return empty patch
26254 if (source == target)
26255 {
26256 return result;
26257 }
26258
26259 if (source.type() != target.type())
26260 {
26261 // different types: replace value
26262 result.push_back(
26263 {
26264 {"op", "replace"}, {"path", path}, {"value", target}
26265 });
26266 return result;
26267 }
26268
26269 switch (source.type())
26270 {
26271 case value_t::array:
26272 {
26273 // first pass: traverse common elements
26274 std::size_t i = 0;
26275 while (i < source.size() && i < target.size())
26276 {
26277 // recursive call to compare array values at index i
26278 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
26279 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26280 ++i;
26281 }
26282
26283 // i now reached the end of at least one array
26284 // in a second pass, traverse the remaining elements
26285
26286 // remove my remaining elements
26287 const auto end_index = static_cast<difference_type>(result.size());
26288 while (i < source.size())
26289 {
26290 // add operations in reverse order to avoid invalid
26291 // indices
26292 result.insert(result.begin() + end_index, object(
26293 {
26294 {"op", "remove"},
26295 {"path", path + "/" + std::to_string(i)}
26296 }));
26297 ++i;
26298 }
26299
26300 // add other remaining elements
26301 while (i < target.size())
26302 {
26303 result.push_back(
26304 {
26305 {"op", "add"},
26306 {"path", path + "/-"},
26307 {"value", target[i]}
26308 });
26309 ++i;
26310 }
26311
26312 break;
26313 }
26314
26315 case value_t::object:
26316 {
26317 // first pass: traverse this object's elements
26318 for (auto it = source.cbegin(); it != source.cend(); ++it)
26319 {
26320 // escape the key name to be used in a JSON patch
26321 const auto path_key = path + "/" + detail::escape(it.key());
26322
26323 if (target.find(it.key()) != target.end())
26324 {
26325 // recursive call to compare object values at key it
26326 auto temp_diff = diff(it.value(), target[it.key()], path_key);
26327 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26328 }
26329 else
26330 {
26331 // found a key that is not in o -> remove it
26332 result.push_back(object(
26333 {
26334 {"op", "remove"}, {"path", path_key}
26335 }));
26336 }
26337 }
26338
26339 // second pass: traverse other object's elements
26340 for (auto it = target.cbegin(); it != target.cend(); ++it)
26341 {
26342 if (source.find(it.key()) == source.end())
26343 {
26344 // found a key that is not in this -> add it
26345 const auto path_key = path + "/" + detail::escape(it.key());
26346 result.push_back(
26347 {
26348 {"op", "add"}, {"path", path_key},
26349 {"value", it.value()}
26350 });
26351 }
26352 }
26353
26354 break;
26355 }
26356
26357 case value_t::null:
26358 case value_t::string:
26359 case value_t::boolean:
26360 case value_t::number_integer:
26361 case value_t::number_unsigned:
26362 case value_t::number_float:
26363 case value_t::binary:
26364 case value_t::discarded:
26365 default:
26366 {
26367 // both primitive type: replace value
26368 result.push_back(
26369 {
26370 {"op", "replace"}, {"path", path}, {"value", target}
26371 });
26372 break;
26373 }
26374 }
26375
26376 return result;
26377 }
26378
26380
26382 // JSON Merge Patch functions //
26384
26387
26430 void merge_patch(const basic_json& apply_patch)
26431 {
26432 if (apply_patch.is_object())
26433 {
26434 if (!is_object())
26435 {
26436 *this = object();
26437 }
26438 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
26439 {
26440 if (it.value().is_null())
26441 {
26442 erase(it.key());
26443 }
26444 else
26445 {
26446 operator[](it.key()).merge_patch(it.value());
26447 }
26448 }
26449 }
26450 else
26451 {
26452 *this = apply_patch;
26453 }
26454 }
26455
26457};
26458
26470{
26471 return j.dump();
26472}
26473} // namespace nlohmann
26474
26476// nonmember support //
26478
26479namespace std // NOLINT(cert-dcl58-cpp)
26480{
26481
26485{
26491 std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
26492 {
26493 return nlohmann::detail::hash(j);
26494 }
26495};
26496
26500template<>
26502{
26508 nlohmann::detail::value_t rhs) const noexcept
26509 {
26510 return nlohmann::detail::operator<(lhs, rhs);
26511 }
26512};
26513
26514// C++20 prohibit function specialization in the std namespace.
26515#ifndef JSON_HAS_CPP_20
26516
26523inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
26524 is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression)
26525 is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
26526{
26527 j1.swap(j2);
26528}
26529
26530#endif
26531
26532} // namespace std
26533
26548inline nlohmann::json operator "" _json(const char* s, std::size_t n)
26549{
26550 return nlohmann::json::parse(s, s + n);
26551}
26552
26567inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
26568{
26569 return nlohmann::json::json_pointer(std::string(s, n));
26570}
26571
26572// #include <nlohmann/detail/macro_unscope.hpp>
26573
26574
26575// restore clang diagnostic settings
26576#if defined(__clang__)
26577 #pragma clang diagnostic pop
26578#endif
26579
26580// clean up
26581#undef JSON_ASSERT
26582#undef JSON_INTERNAL_CATCH
26583#undef JSON_CATCH
26584#undef JSON_THROW
26585#undef JSON_TRY
26586#undef JSON_PRIVATE_UNLESS_TESTED
26587#undef JSON_HAS_CPP_11
26588#undef JSON_HAS_CPP_14
26589#undef JSON_HAS_CPP_17
26590#undef JSON_HAS_CPP_20
26591#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
26592#undef NLOHMANN_BASIC_JSON_TPL
26593#undef JSON_EXPLICIT
26594#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
26595
26596// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
26597
26598
26599#undef JSON_HEDLEY_ALWAYS_INLINE
26600#undef JSON_HEDLEY_ARM_VERSION
26601#undef JSON_HEDLEY_ARM_VERSION_CHECK
26602#undef JSON_HEDLEY_ARRAY_PARAM
26603#undef JSON_HEDLEY_ASSUME
26604#undef JSON_HEDLEY_BEGIN_C_DECLS
26605#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
26606#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
26607#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
26608#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
26609#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
26610#undef JSON_HEDLEY_CLANG_HAS_FEATURE
26611#undef JSON_HEDLEY_CLANG_HAS_WARNING
26612#undef JSON_HEDLEY_COMPCERT_VERSION
26613#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
26614#undef JSON_HEDLEY_CONCAT
26615#undef JSON_HEDLEY_CONCAT3
26616#undef JSON_HEDLEY_CONCAT3_EX
26617#undef JSON_HEDLEY_CONCAT_EX
26618#undef JSON_HEDLEY_CONST
26619#undef JSON_HEDLEY_CONSTEXPR
26620#undef JSON_HEDLEY_CONST_CAST
26621#undef JSON_HEDLEY_CPP_CAST
26622#undef JSON_HEDLEY_CRAY_VERSION
26623#undef JSON_HEDLEY_CRAY_VERSION_CHECK
26624#undef JSON_HEDLEY_C_DECL
26625#undef JSON_HEDLEY_DEPRECATED
26626#undef JSON_HEDLEY_DEPRECATED_FOR
26627#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
26628#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
26629#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
26630#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
26631#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
26632#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
26633#undef JSON_HEDLEY_DIAGNOSTIC_POP
26634#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
26635#undef JSON_HEDLEY_DMC_VERSION
26636#undef JSON_HEDLEY_DMC_VERSION_CHECK
26637#undef JSON_HEDLEY_EMPTY_BASES
26638#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
26639#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
26640#undef JSON_HEDLEY_END_C_DECLS
26641#undef JSON_HEDLEY_FLAGS
26642#undef JSON_HEDLEY_FLAGS_CAST
26643#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
26644#undef JSON_HEDLEY_GCC_HAS_BUILTIN
26645#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
26646#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
26647#undef JSON_HEDLEY_GCC_HAS_EXTENSION
26648#undef JSON_HEDLEY_GCC_HAS_FEATURE
26649#undef JSON_HEDLEY_GCC_HAS_WARNING
26650#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
26651#undef JSON_HEDLEY_GCC_VERSION
26652#undef JSON_HEDLEY_GCC_VERSION_CHECK
26653#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
26654#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
26655#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
26656#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
26657#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
26658#undef JSON_HEDLEY_GNUC_HAS_FEATURE
26659#undef JSON_HEDLEY_GNUC_HAS_WARNING
26660#undef JSON_HEDLEY_GNUC_VERSION
26661#undef JSON_HEDLEY_GNUC_VERSION_CHECK
26662#undef JSON_HEDLEY_HAS_ATTRIBUTE
26663#undef JSON_HEDLEY_HAS_BUILTIN
26664#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
26665#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
26666#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
26667#undef JSON_HEDLEY_HAS_EXTENSION
26668#undef JSON_HEDLEY_HAS_FEATURE
26669#undef JSON_HEDLEY_HAS_WARNING
26670#undef JSON_HEDLEY_IAR_VERSION
26671#undef JSON_HEDLEY_IAR_VERSION_CHECK
26672#undef JSON_HEDLEY_IBM_VERSION
26673#undef JSON_HEDLEY_IBM_VERSION_CHECK
26674#undef JSON_HEDLEY_IMPORT
26675#undef JSON_HEDLEY_INLINE
26676#undef JSON_HEDLEY_INTEL_CL_VERSION
26677#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
26678#undef JSON_HEDLEY_INTEL_VERSION
26679#undef JSON_HEDLEY_INTEL_VERSION_CHECK
26680#undef JSON_HEDLEY_IS_CONSTANT
26681#undef JSON_HEDLEY_IS_CONSTEXPR_
26682#undef JSON_HEDLEY_LIKELY
26683#undef JSON_HEDLEY_MALLOC
26684#undef JSON_HEDLEY_MCST_LCC_VERSION
26685#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
26686#undef JSON_HEDLEY_MESSAGE
26687#undef JSON_HEDLEY_MSVC_VERSION
26688#undef JSON_HEDLEY_MSVC_VERSION_CHECK
26689#undef JSON_HEDLEY_NEVER_INLINE
26690#undef JSON_HEDLEY_NON_NULL
26691#undef JSON_HEDLEY_NO_ESCAPE
26692#undef JSON_HEDLEY_NO_RETURN
26693#undef JSON_HEDLEY_NO_THROW
26694#undef JSON_HEDLEY_NULL
26695#undef JSON_HEDLEY_PELLES_VERSION
26696#undef JSON_HEDLEY_PELLES_VERSION_CHECK
26697#undef JSON_HEDLEY_PGI_VERSION
26698#undef JSON_HEDLEY_PGI_VERSION_CHECK
26699#undef JSON_HEDLEY_PREDICT
26700#undef JSON_HEDLEY_PRINTF_FORMAT
26701#undef JSON_HEDLEY_PRIVATE
26702#undef JSON_HEDLEY_PUBLIC
26703#undef JSON_HEDLEY_PURE
26704#undef JSON_HEDLEY_REINTERPRET_CAST
26705#undef JSON_HEDLEY_REQUIRE
26706#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
26707#undef JSON_HEDLEY_REQUIRE_MSG
26708#undef JSON_HEDLEY_RESTRICT
26709#undef JSON_HEDLEY_RETURNS_NON_NULL
26710#undef JSON_HEDLEY_SENTINEL
26711#undef JSON_HEDLEY_STATIC_ASSERT
26712#undef JSON_HEDLEY_STATIC_CAST
26713#undef JSON_HEDLEY_STRINGIFY
26714#undef JSON_HEDLEY_STRINGIFY_EX
26715#undef JSON_HEDLEY_SUNPRO_VERSION
26716#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
26717#undef JSON_HEDLEY_TINYC_VERSION
26718#undef JSON_HEDLEY_TINYC_VERSION_CHECK
26719#undef JSON_HEDLEY_TI_ARMCL_VERSION
26720#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
26721#undef JSON_HEDLEY_TI_CL2000_VERSION
26722#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
26723#undef JSON_HEDLEY_TI_CL430_VERSION
26724#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
26725#undef JSON_HEDLEY_TI_CL6X_VERSION
26726#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
26727#undef JSON_HEDLEY_TI_CL7X_VERSION
26728#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
26729#undef JSON_HEDLEY_TI_CLPRU_VERSION
26730#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
26731#undef JSON_HEDLEY_TI_VERSION
26732#undef JSON_HEDLEY_TI_VERSION_CHECK
26733#undef JSON_HEDLEY_UNAVAILABLE
26734#undef JSON_HEDLEY_UNLIKELY
26735#undef JSON_HEDLEY_UNPREDICTABLE
26736#undef JSON_HEDLEY_UNREACHABLE
26737#undef JSON_HEDLEY_UNREACHABLE_RETURN
26738#undef JSON_HEDLEY_VERSION
26739#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
26740#undef JSON_HEDLEY_VERSION_DECODE_MINOR
26741#undef JSON_HEDLEY_VERSION_DECODE_REVISION
26742#undef JSON_HEDLEY_VERSION_ENCODE
26743#undef JSON_HEDLEY_WARNING
26744#undef JSON_HEDLEY_WARN_UNUSED_RESULT
26745#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
26746#undef JSON_HEDLEY_FALL_THROUGH
26747
26748
26749
26750#endif // INCLUDE_NLOHMANN_JSON_HPP_
a class to store JSON values
Definition: json.hpp:17717
ValueType & get_to(ValueType &v) const
Definition: json.hpp:20815
void insert(const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:23468
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition: json.hpp:20375
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:18943
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:22120
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:22580
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:22405
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:20429
number_unsigned_t number_unsigned
number (unsigned integer)
Definition: json.hpp:18529
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:25730
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:25702
friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
comparison: equal
Definition: json.hpp:23944
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:21499
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:20198
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:18251
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:23862
NLOHMANN_BASIC_JSON_TPL basic_json_t
workaround type for MSVC
Definition: json.hpp:17738
void update(const_reference j, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:23513
static bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
generate SAX events
Definition: json.hpp:24552
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:20862
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition: json.hpp:24397
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:23154
const_iterator find(KeyT &&key) const
find an element in a JSON object
Definition: json.hpp:22053
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:18984
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition: json.hpp:20363
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:22803
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:26247
static std::vector< std::uint8_t > to_bson(const basic_json &j)
Serializes the given JSON object j to BSON and returns a vector containing the corresponding BSON-rep...
Definition: json.hpp:25102
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:21983
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:22434
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:21145
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:21094
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:22190
binary_t & get_binary()
Definition: json.hpp:20938
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:19563
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:24921
friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:23955
json_value(object_t &&value)
constructor for rvalue objects
Definition: json.hpp:18625
basic_json(const JsonRef &ref)
Definition: json.hpp:19673
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:24826
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:19830
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:19426
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition: json.hpp:18542
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:22376
void assert_invariant(bool check_parents=true) const noexcept
checks the class invariants
Definition: json.hpp:18763
json_value(string_t &&value)
constructor for rvalue strings
Definition: json.hpp:18619
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:22301
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition: json.hpp:18538
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:20423
reference back()
access the last element
Definition: json.hpp:21669
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition: json.hpp:20399
const binary_t & get_binary() const
Definition: json.hpp:20949
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition: json.hpp:20405
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition: json.hpp:24489
StringType string_t
a type for a string
Definition: json.hpp:18153
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:22725
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:22998
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.hpp:17894
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21571
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:17837
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.hpp:20802
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:17835
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:19323
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: json.hpp:21292
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition: json.hpp:18540
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:22988
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:19118
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:17845
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: json.hpp:25626
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:17843
constexpr const binary_t * get_impl_ptr(const binary_t *) const noexcept
get a pointer to the value (binary)
Definition: json.hpp:20453
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:25235
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:18179
iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
Definition: json.hpp:18821
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:23106
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition: json.hpp:20352
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.hpp:19928
static bool accept(IteratorType first, IteratorType last, const bool ignore_comments=false)
Definition: json.hpp:24496
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:21736
static void to_bson(const basic_json &j, detail::output_adapter< std::uint8_t > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
Definition: json.hpp:25117
friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
comparison: not equal
Definition: json.hpp:23989
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: json.hpp:25610
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:20039
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:24168
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:22200
void update(const_iterator first, const_iterator last, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:23546
friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
comparison: less than
Definition: json.hpp:24111
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:20996
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, typename binary_t::subtype_type subtype)
binary (stored with pointer to save storage)
Definition: json.hpp:19380
reference front()
access the first element
Definition: json.hpp:21625
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:20012
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:20170
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
Definition: json.hpp:24838
void swap(object_t &other)
exchanges the values
Definition: json.hpp:23704
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:20220
const_reference front() const
access the first element
Definition: json.hpp:21633
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:19981
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:18390
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:17852
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:24305
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:24146
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:22645
json_value(value_t t)
constructor for empty values of a given type
Definition: json.hpp:18544
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:19700
~basic_json() noexcept
destructor
Definition: json.hpp:19864
static std::vector< std::uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:25024
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:19792
friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:24214
BasicJsonType get_impl(detail::priority_tag< 2 >) const
get special-case overload
Definition: json.hpp:20646
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
Definition: json.hpp:25039
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:23978
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition: json.hpp:23326
friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:24122
json_value m_value
the value of the current element
Definition: json.hpp:24713
boolean_t boolean
boolean
Definition: json.hpp:18525
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: json.hpp:23784
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:24238
void swap(array_t &other)
exchanges the values
Definition: json.hpp:23671
ValueType get_impl(detail::priority_tag< 0 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), std::declval< ValueType & >())))
get a value (explicit)
Definition: json.hpp:20579
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:22368
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:19360
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:22498
json_value(const string_t &value)
constructor for strings
Definition: json.hpp:18616
json_value(const binary_t &value)
constructor for binary arrays (internal type)
Definition: json.hpp:18640
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:20875
json_value(const array_t &value)
constructor for arrays
Definition: json.hpp:18628
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:23374
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:20758
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:25816
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:22271
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:26430
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20516
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:22588
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
Definition: json.hpp:23427
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:18100
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.hpp:20826
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:24192
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
Definition: json.hpp:20417
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition: json.hpp:20393
void destroy(value_t t)
Definition: json.hpp:18645
json_value(const object_t &value)
constructor for objects
Definition: json.hpp:18622
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:21851
json_value(typename binary_t::container_type &&value)
constructor for rvalue binary arrays
Definition: json.hpp:18637
json_value(boolean_t v) noexcept
constructor for booleans
Definition: json.hpp:18536
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:20083
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:22261
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:23608
void clear() noexcept
clears the contents
Definition: json.hpp:22882
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:24260
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:25395
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:20286
static JSON_HEDLEY_RETURNS_NON_NULL T * create(Args &&... args)
helper for exception-safe object creation
Definition: json.hpp:18469
binary_t * binary
binary (stored with pointer to save storage)
Definition: json.hpp:18523
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:19470
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition: json.hpp:23297
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:25512
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:21191
friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than
Definition: json.hpp:24203
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
Definition: json.hpp:25125
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:25773
void swap(binary_t &other)
exchanges the values
Definition: json.hpp:23770
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:17854
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:25496
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:17779
friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:24000
static void to_ubjson(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
Definition: json.hpp:25033
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:22339
void swap(string_t &other)
exchanges the values
Definition: json.hpp:23737
const_reference back() const
access the last element
Definition: json.hpp:21679
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:24031
ValueType get_impl(detail::priority_tag< 1 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >())))
get a value (explicit); special case
Definition: json.hpp:20621
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
binary (stored with pointer to save storage)
Definition: json.hpp:19370
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:20264
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition: json.hpp:20411
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:20242
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:23236
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:25843
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:20441
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition: json.hpp:20381
friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:24249
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: json.hpp:24675
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:22961
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:25252
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:22087
json_value(const typename binary_t::container_type &value)
constructor for binary arrays
Definition: json.hpp:18634
json_value()=default
default constructor (for null values)
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:20113
number_float_t number_float
number (floating-point)
Definition: json.hpp:18531
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition: json.hpp:20387
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:24329
std::less< StringType > object_comparator_t
Definition: json.hpp:17964
string_t * string
string (stored with pointer to save storage)
Definition: json.hpp:18521
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:23124
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
Definition: json.hpp:17767
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:20142
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:17787
static void to_cbor(const basic_json &j, detail::output_adapter< std::uint8_t > o)
Definition: json.hpp:24833
detail::value_t value_t
Definition: json.hpp:17777
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:20435
json_value(binary_t &&value)
constructor for rvalue binary arrays (internal type)
Definition: json.hpp:18643
friend class ::nlohmann::detail::parser
Definition: json.hpp:17723
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
Definition: json.hpp:24933
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition: json.hpp:21341
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:22036
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:19008
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:21254
array_t * array
array (stored with pointer to save storage)
Definition: json.hpp:18519
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:17840
basic_json get_impl(detail::priority_tag< 3 >) const
get special-case overload
Definition: json.hpp:20669
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:18461
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:17781
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:23050
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a pair of character iterators
Definition: json.hpp:24435
number_integer_t number_integer
number (integer)
Definition: json.hpp:18527
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.hpp:22151
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:25379
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:25941
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
Definition: json.hpp:21521
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
Definition: json.hpp:19080
void set_parents()
Definition: json.hpp:18784
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:25880
reference set_parent(reference j, std::size_t old_capacity=std::size_t(-1))
Definition: json.hpp:18834
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:18322
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:23075
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:22230
friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
comparison: less than or equal
Definition: json.hpp:24157
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:24631
static ::nlohmann::detail::parser< basic_json, InputAdapterType > parser(InputAdapterType adapter, detail::parser_callback_t< basic_json >cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
Definition: json.hpp:17745
json_value(array_t &&value)
constructor for rvalue arrays
Definition: json.hpp:18631
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:19242
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:21043
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:23275
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:20313
constexpr auto get_impl(detail::priority_tag< 4 >) const noexcept -> decltype(std::declval< const basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:20682
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:20061
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:23641
binary_t * get_impl_ptr(binary_t *) noexcept
get a pointer to the value (binary)
Definition: json.hpp:20447
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > > > object_t
a type for an object
Definition: json.hpp:18054
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
Definition: json.hpp:20717
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:23204
static void to_msgpack(const basic_json &j, detail::output_adapter< std::uint8_t > o)
Definition: json.hpp:24928
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:23024
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:21948
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition: json.hpp:20470
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:19497
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:17862
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition: json.hpp:20369
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20529
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:22331
an internal type for a backed binary type
Definition: json.hpp:5127
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5146
BinaryType container_type
the type of the underlying container
Definition: json.hpp:5130
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5138
bool m_has_subtype
Definition: json.hpp:5268
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5142
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5164
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:5260
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:5134
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5152
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:5236
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.hpp:5187
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.hpp:5215
std::uint64_t subtype_type
the type of the subtype
Definition: json.hpp:5132
subtype_type m_subtype
Definition: json.hpp:5267
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5158
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:8448
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:8450
bool get_msgpack_array(const std::size_t len)
Definition: json.hpp:10139
binary_reader & operator=(const binary_reader &)=delete
bool get_bson_string(const NumberType len, string_t &result)
Parses a zero-terminated string of length len from the BSON input.
Definition: json.hpp:8602
bool parse_bson_element_internal(const char_int_type element_type, const std::size_t element_type_parse_position)
Read a BSON document element of the given element_type.
Definition: json.hpp:8649
bool parse_bson_array()
Reads an array from the BSON input and passes it to the SAX-parser.
Definition: json.hpp:8765
char_int_type get_ignore_noop()
Definition: json.hpp:10712
bool get_ubjson_high_precision_number()
Definition: json.hpp:10627
binary_reader(InputAdapterType &&adapter) noexcept
create a binary reader
Definition: json.hpp:8464
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:8449
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
Definition: json.hpp:8572
bool get_cbor_array(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:9472
bool get_msgpack_binary(binary_t &result)
reads a MessagePack byte array
Definition: json.hpp:10028
bool get_cbor_object(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:9510
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
Definition: json.hpp:10217
SAX json_sax_t
Definition: json.hpp:8454
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
Definition: json.hpp:8727
bool parse_cbor_internal(const bool get_char, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:8795
bool get_string(const input_format_t format, const NumberType len, string_t &result)
create a string by reading characters from the input
Definition: json.hpp:10780
bool get_cbor_string(string_t &result)
reads a CBOR string
Definition: json.hpp:9283
InputAdapterType ia
input adapter
Definition: json.hpp:10897
bool get_binary(const input_format_t format, const NumberType len, binary_t &result)
create a byte array by reading bytes from the input
Definition: json.hpp:10813
bool parse_ubjson_internal(const bool get_char=true)
Definition: json.hpp:10198
bool unexpect_eof(const input_format_t format, const char *context) const
Definition: json.hpp:10837
binary_reader & operator=(binary_reader &&)=default
bool get_ubjson_size_type(std::pair< std::size_t, char_int_type > &result)
determine the type and size for a container
Definition: json.hpp:10348
std::string get_token_string() const
Definition: json.hpp:10850
bool get_ubjson_value(const char_int_type prefix)
Definition: json.hpp:10389
typename BasicJsonType::string_t string_t
Definition: json.hpp:8452
bool get_msgpack_object(const std::size_t len)
Definition: json.hpp:10161
bool get_bson_binary(const NumberType len, binary_t &result)
Parses a byte array input of length len from the BSON input.
Definition: json.hpp:8623
std::string exception_message(const input_format_t format, const std::string &detail, const std::string &context) const
Definition: json.hpp:10863
std::size_t chars_read
the number of characters read
Definition: json.hpp:10903
typename std::char_traits< char_type >::int_type char_int_type
Definition: json.hpp:8456
binary_reader(const binary_reader &)=delete
char_int_type current
the current character
Definition: json.hpp:10900
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.hpp:8485
json_sax_t * sax
the SAX parser
Definition: json.hpp:10909
bool get_ubjson_size_value(std::size_t &result)
Definition: json.hpp:10271
typename InputAdapterType::char_type char_type
Definition: json.hpp:8455
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
Definition: json.hpp:8547
bool get_number(const input_format_t format, NumberType &result)
Definition: json.hpp:10737
bool get_cbor_binary(binary_t &result)
reads a CBOR byte array
Definition: json.hpp:9378
binary_reader(binary_reader &&)=default
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:8453
char_int_type get()
get next character from the input
Definition: json.hpp:10703
const bool is_little_endian
whether we can assume little endianness
Definition: json.hpp:10906
bool get_msgpack_string(string_t &result)
reads a MessagePack string
Definition: json.hpp:9946
bool get_ubjson_object()
Definition: json.hpp:10552
bool parse_msgpack_internal()
Definition: json.hpp:9566
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:8451
bool get_ubjson_array()
Definition: json.hpp:10490
serialization to CBOR and MessagePack values
Definition: json.hpp:13696
void write_bson_array(const string_t &name, const typename BasicJsonType::array_t &value)
Writes a BSON element with key name and array value.
Definition: json.hpp:14772
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix)
Definition: json.hpp:14963
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition: json.hpp:14394
static std::size_t calc_bson_entry_header_size(const string_t &name, const BasicJsonType &j)
Definition: json.hpp:14602
static constexpr CharType get_ubjson_float_prefix(double)
Definition: json.hpp:15189
void write_bson_entry_header(const string_t &name, const std::uint8_t element_type)
Writes the given element_type and name to the output adapter.
Definition: json.hpp:14617
static std::size_t calc_bson_element_size(const string_t &name, const BasicJsonType &j)
Calculates the size necessary to serialize the JSON value j with its name.
Definition: json.hpp:14806
void write_bson_double(const string_t &name, const double value)
Writes a BSON element with key name and double value value.
Definition: json.hpp:14639
void write_bson_object(const typename BasicJsonType::object_t &value)
Definition: json.hpp:14916
typename BasicJsonType::string_t string_t
Definition: json.hpp:13697
static constexpr CharType get_cbor_float_prefix(float)
Definition: json.hpp:14932
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.hpp:15289
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:13698
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:13707
static constexpr CharType get_msgpack_float_prefix(double)
Definition: json.hpp:14951
CharType ubjson_prefix(const BasicJsonType &j) const noexcept
determine the type prefix of container values
Definition: json.hpp:15103
void write_bson_integer(const string_t &name, const std::int64_t value)
Writes a BSON element with key name and integer value.
Definition: json.hpp:14689
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:15267
void write_bson_string(const string_t &name, const string_t &value)
Writes a BSON element with key name and string value value.
Definition: json.hpp:14657
void write_bson_object_entry(const string_t &name, const typename BasicJsonType::object_t &value)
Writes a BSON element with key name and object value.
Definition: json.hpp:14739
static constexpr CharType get_ubjson_float_prefix(float)
Definition: json.hpp:15184
void write_number(const NumberType n)
Definition: json.hpp:15210
void write_bson_element(const string_t &name, const BasicJsonType &j)
Serializes the JSON value j to BSON and associates it with the key name.
Definition: json.hpp:14854
void write_bson_binary(const string_t &name, const binary_t &value)
Writes a BSON element with key name and binary value value.
Definition: json.hpp:14791
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
Definition: json.hpp:14671
static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t &value)
Definition: json.hpp:14764
void write_bson(const BasicJsonType &j)
Definition: json.hpp:13716
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:13745
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
Definition: json.hpp:14707
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.hpp:15260
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:13699
void write_bson_unsigned(const string_t &name, const BasicJsonType &j)
Writes a BSON element with key name and unsigned value.
Definition: json.hpp:14717
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t &value)
Calculates the size of the BSON serialization of the given JSON-object j.
Definition: json.hpp:14901
static constexpr CharType get_msgpack_float_prefix(float)
Definition: json.hpp:14946
void write_bson_boolean(const string_t &name, const bool value)
Writes a BSON element with key name and boolean value value.
Definition: json.hpp:14629
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:14069
void write_compact_float(const number_float_t n, detail::input_format_t format)
Definition: json.hpp:15226
static std::size_t calc_bson_string_size(const string_t &value)
Definition: json.hpp:14649
static std::size_t calc_bson_integer_size(const std::int64_t value)
Definition: json.hpp:14679
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
Definition: json.hpp:14749
static constexpr CharType get_cbor_float_prefix(double)
Definition: json.hpp:14937
general exception of the basic_json class
Definition: json.hpp:2766
const int id
the id of the exception
Definition: json.hpp:2775
static std::string diagnostics(const BasicJsonType &leaf_element)
Definition: json.hpp:2787
static std::string name(const std::string &ename, int id_)
Definition: json.hpp:2781
std::runtime_error m
an exception object as storage for error messages
Definition: json.hpp:2852
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:2769
Definition: json.hpp:5463
std::FILE * m_file
the file pointer to read from
Definition: json.hpp:5486
file_input_adapter(const file_input_adapter &)=delete
file_input_adapter(file_input_adapter &&) noexcept=default
char char_type
Definition: json.hpp:5465
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:5479
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: json.hpp:5523
~input_stream_adapter()
Definition: json.hpp:5504
input_stream_adapter & operator=(input_stream_adapter &)=delete
input_stream_adapter(const input_stream_adapter &)=delete
std::istream * is
the associated input stream
Definition: json.hpp:5546
char char_type
Definition: json.hpp:5502
input_stream_adapter & operator=(input_stream_adapter &&)=delete
std::streambuf * sb
Definition: json.hpp:5547
std::char_traits< char >::int_type get_character()
Definition: json.hpp:5533
input_stream_adapter(std::istream &i)
Definition: json.hpp:5514
exception indicating errors with iterators
Definition: json.hpp:2989
static invalid_iterator create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition: json.hpp:2992
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.hpp:11625
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:12088
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:12218
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition: json.hpp:12079
iter_impl const operator--(int)
post-decrement (it–)
Definition: json.hpp:11991
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:11815
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:11652
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:12002
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:12229
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.hpp:11734
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:11661
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:11854
iter_impl(iter_impl &&) noexcept=default
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:12141
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:11656
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:11759
pointer operator->() const
dereference the iterator
Definition: json.hpp:11898
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.hpp:11724
iter_impl const operator++(int)
post-increment (it++)
Definition: json.hpp:11940
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:11749
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:12321
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:12196
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:12207
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.hpp:12296
bool operator==(const IterImpl &other) const
comparison: equal
Definition: json.hpp:12043
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:12132
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:11650
reference value() const
return the value of an iterator
Definition: json.hpp:12312
typename BasicJsonType::object_t object_t
Definition: json.hpp:11634
friend other_iter_impl
allow basic_json to access private members
Definition: json.hpp:11629
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:11951
friend BasicJsonType
Definition: json.hpp:11630
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:12258
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:12123
std::bidirectional_iterator_tag iterator_category
Definition: json.hpp:11647
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:12150
typename BasicJsonType::array_t array_t
Definition: json.hpp:11635
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:12187
IteratorType anchor
the iterator
Definition: json.hpp:4466
std::input_iterator_tag iterator_category
Definition: json.hpp:4461
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition: json.hpp:4462
const string_type empty_str
an empty string (to return a reference for primitive values)
Definition: json.hpp:4474
iteration_proxy_value(IteratorType it) noexcept
Definition: json.hpp:4477
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.hpp:4503
std::size_t array_index_last
last stringified array index
Definition: json.hpp:4470
string_type array_index_str
a string representation of the array index
Definition: json.hpp:4472
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:4545
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:4488
std::size_t array_index
an index for arrays (used to create key names)
Definition: json.hpp:4468
iteration_proxy_value & operator*()
dereference operator (needed for range-based for)
Definition: json.hpp:4482
std::ptrdiff_t difference_type
Definition: json.hpp:4457
const string_type & key() const
return key of the iterator
Definition: json.hpp:4509
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.hpp:4497
proxy class for the items() function
Definition: json.hpp:4553
iteration_proxy_value< IteratorType > begin() noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:4564
iteration_proxy_value< IteratorType > end() noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:4570
IteratorType::reference container
the container to iterate
Definition: json.hpp:4556
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:4560
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: json.hpp:5557
IteratorType end
Definition: json.hpp:5577
IteratorType current
Definition: json.hpp:5576
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:5559
std::char_traits< char_type >::int_type get_character()
Definition: json.hpp:5563
bool empty() const
Definition: json.hpp:5582
Definition: json.hpp:13461
value_type const * value_ref
Definition: json.hpp:13512
json_ref(json_ref &&) noexcept=default
value_type owned_value
Definition: json.hpp:13511
value_type const & operator*() const
Definition: json.hpp:13500
BasicJsonType value_type
Definition: json.hpp:13463
json_ref(Args &&... args)
Definition: json.hpp:13480
json_ref(const value_type &value)
Definition: json.hpp:13469
value_type const * operator->() const
Definition: json.hpp:13505
json_ref(std::initializer_list< json_ref > init)
Definition: json.hpp:13473
json_ref(value_type &&value)
Definition: json.hpp:13465
value_type moved_or_copied() const
Definition: json.hpp:13491
a template for a reverse iterator class
Definition: json.hpp:12363
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:12372
json_reverse_iterator const operator--(int)
post-decrement (it–)
Definition: json.hpp:12391
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:12369
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:12415
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:12403
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:12367
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:12376
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:12427
std::ptrdiff_t difference_type
Definition: json.hpp:12365
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:12421
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:12409
json_reverse_iterator const operator++(int)
post-increment (it++)
Definition: json.hpp:12379
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:12433
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:12397
reference value() const
return the value of an iterator
Definition: json.hpp:12440
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:12385
Definition: json.hpp:6548
bool end_array()
Definition: json.hpp:6611
typename BasicJsonType::string_t string_t
Definition: json.hpp:6553
bool binary(binary_t &)
Definition: json.hpp:6586
bool boolean(bool)
Definition: json.hpp:6561
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6550
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6552
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6554
bool key(string_t &)
Definition: json.hpp:6596
bool start_object(std::size_t=std::size_t(-1))
Definition: json.hpp:6591
bool start_array(std::size_t=std::size_t(-1))
Definition: json.hpp:6606
bool end_object()
Definition: json.hpp:6601
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.hpp:6616
bool number_integer(number_integer_t)
Definition: json.hpp:6566
bool string(string_t &)
Definition: json.hpp:6581
bool number_unsigned(number_unsigned_t)
Definition: json.hpp:6571
bool null()
Definition: json.hpp:6556
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6551
bool number_float(number_float_t, const string_t &)
Definition: json.hpp:6576
typename BasicJsonType::string_t string_t
Definition: json.hpp:6246
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
bool start_object(std::size_t len)
Definition: json.hpp:6308
bool key(string_t &val)
Definition: json.hpp:6326
constexpr bool is_errored() const
Definition: json.hpp:6441
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6244
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6243
std::pair< bool, BasicJsonType * > handle_value(Value &&v, const bool skip_callback=false)
Definition: json.hpp:6463
bool null()
Definition: json.hpp:6266
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.hpp:6248
bool start_array(std::size_t len)
Definition: json.hpp:6379
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6247
bool binary(binary_t &val)
Definition: json.hpp:6302
bool number_integer(number_integer_t val)
Definition: json.hpp:6278
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:6527
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6245
bool end_array()
Definition: json.hpp:6396
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.hpp:6249
bool boolean(bool val)
Definition: json.hpp:6272
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6284
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
bool string(string_t &val)
Definition: json.hpp:6296
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6290
bool end_object()
Definition: json.hpp:6343
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:6429
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition: json.hpp:6251
SAX implementation to create a JSON value from SAX events.
Definition: json.hpp:6067
bool start_array(std::size_t len)
Definition: json.hpp:6159
json_sax_dom_parser(const json_sax_dom_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:6073
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
bool number_unsigned(number_unsigned_t val)
Definition: json.hpp:6109
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6069
bool boolean(bool val)
Definition: json.hpp:6097
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.hpp:6179
JSON_HEDLEY_RETURNS_NON_NULL BasicJsonType * handle_value(Value &&v)
Definition: json.hpp:6205
bool string(string_t &val)
Definition: json.hpp:6121
bool end_object()
Definition: json.hpp:6152
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6070
bool start_object(std::size_t len)
Definition: json.hpp:6133
bool null()
Definition: json.hpp:6091
bool binary(binary_t &val)
Definition: json.hpp:6127
constexpr bool is_errored() const
Definition: json.hpp:6191
bool key(string_t &val)
Definition: json.hpp:6145
json_sax_dom_parser(json_sax_dom_parser &&)=default
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6071
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:6228
bool number_float(number_float_t val, const string_t &)
Definition: json.hpp:6115
bool end_array()
Definition: json.hpp:6171
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json.hpp:6080
typename BasicJsonType::string_t string_t
Definition: json.hpp:6072
bool number_integer(number_integer_t val)
Definition: json.hpp:6103
Definition: json.hpp:6655
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition: json.hpp:6682
token_type
token types for the parser
Definition: json.hpp:6659
@ value_float
an floating point number – use get_number_float() for actual value
@ begin_array
the character for array begin [
@ value_string
a string – use get_string() for actual value
@ end_array
the character for array end ]
@ uninitialized
indicating the scanner is uninitialized
@ parse_error
indicating a parse error
@ value_integer
a signed integer – use get_number_integer() for actual value
@ value_separator
the value separator ,
@ end_object
the character for object end }
@ begin_object
the character for object begin {
@ value_unsigned
an unsigned integer – use get_number_unsigned() for actual value
@ end_of_input
indicating the end of the input buffer
@ literal_or_value
a literal or the begin of a value (only for diagnostics)
lexical analysis
Definition: json.hpp:6732
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:8050
number_float_t value_float
Definition: json.hpp:8245
const bool ignore_comments
whether comments should be ignored (true) or signaled as errors (false)
Definition: json.hpp:8222
void add(char_int_type c)
add a character to token_buffer
Definition: json.hpp:8021
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition: json.hpp:7940
token_type scan()
Definition: json.hpp:8129
bool next_unget
whether the next get() call should just return current
Definition: json.hpp:8228
char_int_type current
the current character
Definition: json.hpp:8225
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:6735
void skip_whitespace()
Definition: json.hpp:8120
typename std::char_traits< char_type >::int_type char_int_type
Definition: json.hpp:6738
static JSON_HEDLEY_PURE char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition: json.hpp:6763
number_integer_t value_integer
Definition: json.hpp:8243
InputAdapterType ia
input adapter
Definition: json.hpp:8219
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:6733
lexer & operator=(lexer &&)=default
static void strtof(float &f, const char *str, char **endptr) noexcept
Definition: json.hpp:7532
const char_int_type decimal_point_char
the decimal point
Definition: json.hpp:8248
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:8106
const char * error_message
a description of occurred lexer errors
Definition: json.hpp:8240
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition: json.hpp:6743
position_t position
the start position of the current token
Definition: json.hpp:8231
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8060
std::vector< char_type > token_string
raw input token string (for error messages)
Definition: json.hpp:8234
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:8032
typename lexer_base< BasicJsonType >::token_type token_type
Definition: json.hpp:6741
typename InputAdapterType::char_type char_type
Definition: json.hpp:6737
char_int_type get()
Definition: json.hpp:7957
token_type scan_number()
scan a number literal
Definition: json.hpp:7589
lexer & operator=(lexer &)=delete
void unget()
unget current character (read it again on next get)
Definition: json.hpp:7994
token_type scan_string()
scan a string literal
Definition: json.hpp:6874
lexer(const lexer &)=delete
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:8038
string_t token_buffer
buffer for variable-length tokens (numbers, strings)
Definition: json.hpp:8237
token_type scan_literal(const char_type *literal_text, const std::size_t length, token_type return_type)
Definition: json.hpp:7920
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:8044
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition: json.hpp:6789
std::string get_token_string() const
Definition: json.hpp:8068
number_unsigned_t value_unsigned
Definition: json.hpp:8244
lexer(lexer &&)=default
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:6734
bool next_byte_in_range(std::initializer_list< char_int_type > ranges)
check if the next byte(s) are inside a given range
Definition: json.hpp:6837
typename BasicJsonType::string_t string_t
Definition: json.hpp:6736
bool scan_comment()
scan a comment
Definition: json.hpp:7464
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:8093
exception indicating other library errors
Definition: json.hpp:3131
static other_error create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition: json.hpp:3134
exception indicating access out of the defined range
Definition: json.hpp:3092
static out_of_range create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition: json.hpp:3095
Definition: json.hpp:13657
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.hpp:13664
output_adapter(std::vector< CharType, AllocatorType > &vec)
Definition: json.hpp:13660
output_adapter(StringType &s)
Definition: json.hpp:13668
output adapter for output streams
Definition: json.hpp:13609
void write_character(CharType c) override
Definition: json.hpp:13615
std::basic_ostream< CharType > & stream
Definition: json.hpp:13627
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.hpp:13611
output adapter for basic_string
Definition: json.hpp:13634
void write_character(CharType c) override
Definition: json.hpp:13640
StringType & str
Definition: json.hpp:13652
output_string_adapter(StringType &s) noexcept
Definition: json.hpp:13636
output adapter for byte vectors
Definition: json.hpp:13584
output_vector_adapter(std::vector< CharType, AllocatorType > &vec) noexcept
Definition: json.hpp:13586
void write_character(CharType c) override
Definition: json.hpp:13590
std::vector< CharType, AllocatorType > & v
Definition: json.hpp:13602
exception indicating a parse error
Definition: json.hpp:2901
parse_error(int id_, std::size_t byte_, const char *what_arg)
Definition: json.hpp:2941
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, const BasicJsonType &context)
Definition: json.hpp:2921
const std::size_t byte
byte index of the parse error
Definition: json.hpp:2938
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, const BasicJsonType &context)
create a parse error exception
Definition: json.hpp:2913
static std::string position_string(const position_t &pos)
Definition: json.hpp:2944
syntax analysis
Definition: json.hpp:10978
lexer_t m_lexer
the lexer
Definition: json.hpp:11418
bool sax_parse(SAX *sax, const bool strict=true)
Definition: json.hpp:11078
token_type get_token()
get next token from lexer
Definition: json.hpp:11378
token_type last_token
the type of the last read token
Definition: json.hpp:11416
parser(InputAdapterType &&adapter, const parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition: json.hpp:10988
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:11070
typename BasicJsonType::string_t string_t
Definition: json.hpp:10982
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:10980
typename lexer_t::token_type token_type
Definition: json.hpp:10984
bool sax_parse_internal(SAX *sax)
Definition: json.hpp:11097
const parser_callback_t< BasicJsonType > callback
callback function
Definition: json.hpp:11414
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:11010
std::string exception_message(const token_type expected, const std::string &context)
Definition: json.hpp:11383
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:10981
const bool allow_exceptions
whether to throw exceptions in case of errors
Definition: json.hpp:11420
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:10979
Definition: json.hpp:11452
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.hpp:11502
primitive_iterator_t & operator++() noexcept
Definition: json.hpp:11514
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:11487
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.hpp:11546
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:11481
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:11497
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:11469
primitive_iterator_t const operator++(int) noexcept
Definition: json.hpp:11520
static constexpr difference_type end_value
Definition: json.hpp:11456
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:11492
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.hpp:11509
primitive_iterator_t & operator--() noexcept
Definition: json.hpp:11527
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:11475
constexpr difference_type get_value() const noexcept
Definition: json.hpp:11463
primitive_iterator_t const operator--(int) noexcept
Definition: json.hpp:11533
std::ptrdiff_t difference_type
Definition: json.hpp:11454
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.hpp:11540
static constexpr difference_type begin_value
Definition: json.hpp:11455
Definition: json.hpp:16467
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.hpp:17377
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:16471
const std::lconv * loc
the locale
Definition: json.hpp:17362
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition: json.hpp:17359
static constexpr std::uint8_t UTF8_ACCEPT
Definition: json.hpp:16473
serializer(serializer &&)=delete
serializer & operator=(serializer &&)=delete
const char decimal_point
the locale's decimal point character
Definition: json.hpp:17366
std::uint8_t state
Definition: json.hpp:16809
std::size_t bytes
Definition: json.hpp:16810
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:16469
const char thousands_sep
the locale's thousand separator character
Definition: json.hpp:17364
serializer & operator=(const serializer &)=delete
std::size_t undumped_chars
Definition: json.hpp:16814
static constexpr std::uint8_t UTF8_REJECT
Definition: json.hpp:16474
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: json.hpp:16522
const char indent_char
the indentation character
Definition: json.hpp:17372
std::size_t bytes_after_last_accept
Definition: json.hpp:16813
std::array< char, 512 > string_buffer
string buffer
Definition: json.hpp:17369
typename BasicJsonType::binary_t::value_type binary_char_t
Definition: json.hpp:16472
JSON_PRIVATE_UNLESS_TESTED const bool ensure_ascii
Definition: json.hpp:16807
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.hpp:16482
typename BasicJsonType::string_t string_t
Definition: json.hpp:16468
serializer(const serializer &)=delete
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:16470
string_t indent_string
the indentation string
Definition: json.hpp:17374
Definition: json.hpp:5881
contiguous_bytes_input_adapter && get()
Definition: json.hpp:5899
span_input_adapter(CharT b, std::size_t l)
Definition: json.hpp:5889
contiguous_bytes_input_adapter ia
Definition: json.hpp:5905
span_input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:5896
exception indicating executing a member function with a wrong type
Definition: json.hpp:3044
static type_error create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition: json.hpp:3047
void fill_buffer()
Definition: json.hpp:5743
std::char_traits< char >::int_type get_character() noexcept
Definition: json.hpp:5722
std::size_t utf8_bytes_index
index to the utf8_codes array for the next valid byte
Definition: json.hpp:5752
BaseInputAdapter base_adapter
Definition: json.hpp:5740
char char_type
Definition: json.hpp:5717
std::size_t utf8_bytes_filled
number of valid bytes in the utf8_codes array
Definition: json.hpp:5754
wide_string_input_adapter(BaseInputAdapter base)
Definition: json.hpp:5719
std::array< std::char_traits< char >::int_type, 4 > utf8_bytes
a buffer for UTF-8 bytes
Definition: json.hpp:5749
JSON Pointer.
Definition: json.hpp:12475
std::vector< std::string > reference_tokens
the reference tokens
Definition: json.hpp:13442
JSON_PRIVATE_UNLESS_TESTED JSON pointer has no BasicJsonType()))
json_pointer & operator/=(std::string token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:12576
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:12552
std::string to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:12520
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
Definition: json.hpp:13057
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for equality
Definition: json.hpp:13418
result reference_tokens
Definition: json.hpp:12841
void pop_back()
remove last reference token
Definition: json.hpp:12702
const std::string & back() const
return last reference token
Definition: json.hpp:12726
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
Definition: json.hpp:13105
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:12773
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for inequality
Definition: json.hpp:13435
void push_back(const std::string &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:12748
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:12502
return result
Definition: json.hpp:12842
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition: json.hpp:12618
bool contains(const BasicJsonType *ptr) const
Definition: json.hpp:13153
static BasicJsonType unflatten(const BasicJsonType &value)
Definition: json.hpp:13380
friend json_pointer operator/(const json_pointer &ptr, std::string token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.hpp:12639
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
Definition: json.hpp:12854
static void flatten(const std::string &reference_string, const BasicJsonType &value, BasicJsonType &result)
Definition: json.hpp:13309
void push_back(std::string &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:12754
BasicJsonType & get_checked(BasicJsonType *ptr) const
Definition: json.hpp:13000
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:12598
static BasicJsonType::size_type array_index(const std::string &s)
Definition: json.hpp:12789
json_pointer result
Definition: json.hpp:12840
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
Definition: json.hpp:12933
friend json_pointer operator/(const json_pointer &ptr, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition: json.hpp:12659
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:12677
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
Definition: json.hpp:13241
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition: json.hpp:4615
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.hpp:2416
#define JSON_HEDLEY_CONST
Definition: json.hpp:1670
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: json.hpp:954
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: json.hpp:1300
#define JSON_PRIVATE_UNLESS_TESTED
Definition: json.hpp:2379
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.hpp:35
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.hpp:1565
#define JSON_HEDLEY_NON_NULL(...)
Definition: json.hpp:1458
#define JSON_INTERNAL_CATCH(exception)
Definition: json.hpp:2346
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: json.hpp:1899
#define JSON_CATCH(exception)
Definition: json.hpp:2345
#define JSON_ASSERT(x)
Definition: json.hpp:2372
#define JSON_THROW(exception)
Definition: json.hpp:2343
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.hpp:33
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.hpp:2425
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.hpp:1566
#define JSON_TRY
Definition: json.hpp:2344
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.hpp:34
#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)
Definition: json.hpp:2591
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: json.hpp:955
#define JSON_EXPLICIT
Definition: json.hpp:2628
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition: json.hpp:1248
#define JSON_HEDLEY_PURE
Definition: json.hpp:1639
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.hpp:16144
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition: json.hpp:16296
Target reinterpret_bits(const Source source)
Definition: json.hpp:15364
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:15505
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.hpp:15808
constexpr int kGamma
Definition: json.hpp:15628
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition: json.hpp:15862
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:16244
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:15903
constexpr int kAlpha
Definition: json.hpp:15627
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:15644
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:3179
typename T::reference reference_t
Definition: json.hpp:3554
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:147
static void unescape(std::string &s)
string unescaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2688
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.hpp:3563
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.hpp:4871
value_type_t< iterator_traits< iterator_t< T > > > range_value_t
Definition: json.hpp:3717
value_t
the JSON type enumeration
Definition: json.hpp:121
@ number_integer
number value (signed integer)
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.hpp:3962
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.hpp:3283
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
Definition: json.hpp:8319
typename T::pointer pointer_t
Definition: json.hpp:3551
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.hpp:8292
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: json.hpp:10969
typename T::difference_type difference_type_t
Definition: json.hpp:3548
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.hpp:2277
void int_to_string(string_type &target, std::size_t value)
Definition: json.hpp:4448
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.hpp:4117
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.hpp:8304
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.hpp:8276
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: json.hpp:8296
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.hpp:8280
JSON_HEDLEY_RETURNS_NON_NULL char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition: json.hpp:16381
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.hpp:4994
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition: json.hpp:3714
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.hpp:2290
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.hpp:3165
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:8420
@ store
store tags as binary type
@ error
throw a parse_error exception in case of a tag
parse_event_t
Definition: json.hpp:10952
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
error_handler_t
how to treat decoding errors
Definition: json.hpp:16459
@ strict
throw a type_error exception in case of invalid UTF-8
@ ignore
ignore invalid UTF-8 sequences
@ replace
replace invalid UTF-8 sequences with U+FFFD
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.hpp:8300
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: json.hpp:5797
typename T::key_type key_type_t
Definition: json.hpp:3542
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: json.hpp:5297
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:5315
static bool little_endianness(int num=1) noexcept
determine system byte order
Definition: json.hpp:8433
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition: json.hpp:3267
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.hpp:8284
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: json.hpp:2286
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: json.hpp:2283
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.hpp:8311
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 > >, priority_tag< 0 >)
Definition: json.hpp:4306
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.hpp:3976
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.hpp:2271
typename make_void< Ts... >::type void_t
Definition: json.hpp:2233
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.hpp:3275
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:13579
typename T::mapped_type mapped_type_t
Definition: json.hpp:3539
std::string escape(std::string s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2674
input_format_t
the supported input formats
Definition: json.hpp:5451
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition: json.hpp:4300
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.hpp:3566
std::array< T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType &&j, identity_tag< std::array< T, sizeof...(Idx)> >, index_sequence< Idx... >)
Definition: json.hpp:4200
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: json.hpp:5854
decltype(std::declval< T & >().null()) null_function_t
Definition: json.hpp:8272
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:4579
void replace_substring(std::string &s, const std::string &f, const std::string &t)
replace all occurrences of a substring by another string
Definition: json.hpp:2656
typename T::iterator_category iterator_category_t
Definition: json.hpp:3557
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: json.hpp:8288
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.hpp:8314
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.hpp:8307
T conditional_static_cast(U value)
Definition: json.hpp:3936
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.hpp:3560
typename T::value_type value_type_t
Definition: json.hpp:3545
namespace for Niels Lohmann
Definition: json.hpp:89
basic_json<> json
default JSON class
Definition: json.hpp:3472
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:26469
STL namespace.
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:26523
default JSONSerializer template argument
Definition: json.hpp:5043
static auto from_json(BasicJsonType &&j, TargetType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition: json.hpp:5056
static auto from_json(BasicJsonType &&j) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))
convert a JSON value to any value type
Definition: json.hpp:5076
static auto to_json(BasicJsonType &j, TargetType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< TargetType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< TargetType >(val)), void())
convert any value type to a JSON value
Definition: json.hpp:5093
Definition: json.hpp:3628
Definition: json.hpp:2258
Default type
Definition: json.hpp:2260
std::false_type value_t
Definition: json.hpp:2259
Definition: json.hpp:15492
diyfp plus
Definition: json.hpp:15495
diyfp w
Definition: json.hpp:15493
diyfp minus
Definition: json.hpp:15494
std::uint64_t f
Definition: json.hpp:15632
int k
Definition: json.hpp:15634
int e
Definition: json.hpp:15633
Definition: json.hpp:15374
static constexpr int kPrecision
Definition: json.hpp:15375
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:15463
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition: json.hpp:15480
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:15398
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: json.hpp:15380
int e
Definition: json.hpp:15378
std::uint64_t f
Definition: json.hpp:15377
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:15386
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.hpp:4783
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.hpp:4812
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.hpp:4796
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.hpp:4771
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.hpp:4761
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: json.hpp:4700
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: json.hpp:4709
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.hpp:4654
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.hpp:4722
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.hpp:4748
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.hpp:4735
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.hpp:4841
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.hpp:4831
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.hpp:4852
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.hpp:4676
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.hpp:4687
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.hpp:4667
Definition: json.hpp:4395
auto operator()(const BasicJsonType &j, T &&val) const noexcept(noexcept(from_json(j, std::forward< T >(val)))) -> decltype(from_json(j, std::forward< T >(val)))
Definition: json.hpp:4397
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3585
Definition: json.hpp:3570
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3600
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.hpp:3615
Definition: json.hpp:3610
Definition: json.hpp:3314
Definition: json.hpp:3207
T value_type
Definition: json.hpp:3208
static constexpr std::size_t size() noexcept
Definition: json.hpp:3209
an iterator value
Definition: json.hpp:11567
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:11573
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:11571
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:11569
Definition: json.hpp:3516
static constexpr auto value
Definition: json.hpp:3789
Definition: json.hpp:3908
Definition: json.hpp:3724
static constexpr auto value
Definition: json.hpp:3796
Definition: json.hpp:3661
Definition: json.hpp:2274
Definition: json.hpp:3578
static constexpr bool value
Definition: json.hpp:3579
typename std::iterator_traits< T >::value_type value_type
Definition: json.hpp:5774
Definition: json.hpp:3677
Definition: json.hpp:3529
Definition: json.hpp:3924
char x[2]
Definition: json.hpp:3925
Definition: json.hpp:3920
@ value
Definition: json.hpp:3931
char one
Definition: json.hpp:3921
static one test(decltype(&C::capacity))
Definition: json.hpp:3696
detected_t< result_of_end, t_ref > sentinel
Definition: json.hpp:3701
detected_t< result_of_begin, t_ref > iterator
Definition: json.hpp:3700
static constexpr auto is_iterator_begin
Definition: json.hpp:3706
typename std::add_lvalue_reference< T >::type t_ref
Definition: json.hpp:3698
static constexpr bool value
Definition: json.hpp:3710
typename BasicJsonType::string_t string_t
Definition: json.hpp:8362
typename BasicJsonType::exception exception_t
Definition: json.hpp:8364
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:8359
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:8361
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:8363
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:8360
Definition: json.hpp:8323
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:8330
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:8329
typename BasicJsonType::exception exception_t
Definition: json.hpp:8333
static constexpr bool value
Definition: json.hpp:8336
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:8328
typename BasicJsonType::string_t string_t
Definition: json.hpp:8331
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:8332
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:5785
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.hpp:5762
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.hpp:5765
iterator_input_adapter< iterator_type > adapter_type
Definition: json.hpp:5763
IteratorType iterator_type
Definition: json.hpp:5761
std::random_access_iterator_tag iterator_category
Definition: json.hpp:3375
Definition: json.hpp:3363
Definition: json.hpp:3344
Definition: json.hpp:2230
void type
Definition: json.hpp:2231
Definition: json.hpp:3635
Definition: json.hpp:2244
nonesuch(nonesuch const &)=delete
void operator=(nonesuch &&)=delete
nonesuch(nonesuch const &&)=delete
void operator=(nonesuch const &)=delete
abstract output adapter interface
Definition: json.hpp:13565
virtual void write_characters(const CharType *s, std::size_t length)=0
virtual void write_character(CharType c)=0
output_adapter_protocol(output_adapter_protocol &&) noexcept=default
output_adapter_protocol(const output_adapter_protocol &)=default
struct to capture the start position of the current token
Definition: json.hpp:2708
std::size_t lines_read
the number of lines read
Definition: json.hpp:2714
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:2712
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:2710
Definition: json.hpp:3290
Definition: json.hpp:3296
static constexpr T value
Definition: json.hpp:3297
Definition: json.hpp:5014
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: json.hpp:5016
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition: json.hpp:3248
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:5654
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.hpp:5596
SAX interface.
Definition: json.hpp:5936
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
virtual bool string(string_t &val)=0
a string was read
virtual bool null()=0
a null value was read
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:5937
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:5941
virtual bool end_array()=0
the end of an array was read
virtual bool key(string_t &val)=0
an object key was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:5938
virtual bool binary(binary_t &val)=0
a binary string was read
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:5939
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
json_sax(json_sax &&) noexcept=default
virtual bool boolean(bool val)=0
a boolean value was read
json_sax(const json_sax &)=default
virtual bool end_object()=0
the end of an object was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
typename BasicJsonType::string_t string_t
Definition: json.hpp:5940
virtual bool number_float(number_float_t val, const string_t &s)=0
an floating-point number was read
virtual bool number_integer(number_integer_t val)=0
an integer number was read
Definition: json.hpp:17409
T & at(const Key &key)
Definition: json.hpp:17450
ordered_map(std::initializer_list< T > init, const Allocator &alloc=Allocator())
Definition: json.hpp:17424
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:17412
T mapped_type
Definition: json.hpp:17411
const T & at(const Key &key) const
Definition: json.hpp:17463
iterator find(const Key &key)
Definition: json.hpp:17560
iterator erase(iterator pos)
Definition: json.hpp:17495
void insert(InputIt first, InputIt last)
Definition: json.hpp:17607
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:17584
const_iterator find(const Key &key) const
Definition: json.hpp:17572
Key key_type
Definition: json.hpp:17410
size_type erase(const Key &key)
Definition: json.hpp:17476
T & operator[](const Key &key)
Definition: json.hpp:17440
iterator erase(iterator first, iterator last)
Definition: json.hpp:17500
ordered_map(const Allocator &alloc=Allocator())
Definition: json.hpp:17420
typename std::enable_if< std::is_convertible< typename std::iterator_traits< InputIt >::iterator_category, std::input_iterator_tag >::value >::type require_input_iter
Definition: json.hpp:17604
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:17422
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:17589
size_type count(const Key &key) const
Definition: json.hpp:17548
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:17427
const T & operator[](const Key &key) const
Definition: json.hpp:17445
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
return a hash value for a JSON object
Definition: json.hpp:26491
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:26507